From 417922125e2f3859c0a2743126a7d09d92bbea9c Mon Sep 17 00:00:00 2001 From: Greg Nazario Date: Thu, 3 Oct 2024 10:35:20 -0700 Subject: [PATCH] [integration-guides] Separate out integration guides, add exchange guide (#633) * [integration-guides] Separate out integration guides, add exchange guide * [network] Fix networks page to contain all information * [faucet] Replace faucet usage with the official SDKs instead * [refactor] Remove system integrators guide from being referenced elsewhere * [accounts] fix typo in accounts page * [exchanges] make final update to exchange guide --- apps/nextra/pages/en/build/apis.mdx | 2 +- .../nextra/pages/en/build/apis/faucet-api.mdx | 87 +- .../pages/en/build/apis/fullnode-rest-api.mdx | 6 +- .../en/build/cli/running-a-local-network.mdx | 2 +- apps/nextra/pages/en/build/guides/_meta.tsx | 10 +- .../4-fetch-data-from-chain.mdx | 2 +- .../pages/en/build/guides/exchanges.mdx | 1180 +++++++++++++++++ .../build/guides/system-integrators-guide.mdx | 445 ++----- .../pages/en/network/blockchain/accounts.mdx | 2 +- .../pages/en/network/blockchain/events.mdx | 2 +- apps/nextra/pages/en/network/glossary.mdx | 11 +- .../en/network/nodes/building-from-source.mdx | 2 +- .../localnet/local-development-network.mdx | 2 +- .../pages/en/network/nodes/networks.mdx | 41 +- apps/nextra/pages/zh/build/apis.mdx | 2 +- .../nextra/pages/zh/build/apis/faucet-api.mdx | 6 +- .../pages/zh/build/apis/fullnode-rest-api.mdx | 6 +- .../zh/build/cli/running-a-local-network.mdx | 2 +- .../zh/network/nodes/building-from-source.mdx | 2 +- 19 files changed, 1410 insertions(+), 402 deletions(-) create mode 100644 apps/nextra/pages/en/build/guides/exchanges.mdx diff --git a/apps/nextra/pages/en/build/apis.mdx b/apps/nextra/pages/en/build/apis.mdx index 3c82b8970..6d29cc266 100644 --- a/apps/nextra/pages/en/build/apis.mdx +++ b/apps/nextra/pages/en/build/apis.mdx @@ -52,7 +52,7 @@ _submitting_ transactions to the Aptos Blockchain. It also supports transaction ## Faucet (Only Testnet/Devnet) - + Faucet API This API provides the ability to receive test tokens on devnet and testnet. Its primary purpose is the development diff --git a/apps/nextra/pages/en/build/apis/faucet-api.mdx b/apps/nextra/pages/en/build/apis/faucet-api.mdx index b4d291420..465d16f4f 100644 --- a/apps/nextra/pages/en/build/apis/faucet-api.mdx +++ b/apps/nextra/pages/en/build/apis/faucet-api.mdx @@ -6,66 +6,71 @@ title: "Faucet API" The faucet allows users to get test `APT` on Devnet and Testnet. It is not available on Mainnet. -## Differences between devnet and testnet - -What are the differences between devnet and testnet? Effectively none. In the -past, the testnet faucet had a Captcha in front of it, making it unqueryable -by -normal means. This is no longer true. - The endpoints for each faucet are: - Devnet: https://faucet.devnet.aptoslabs.com - Testnet: https://faucet.testnet.aptoslabs.com -## Integrating with the faucet +## Using the faucet -See the [System Integrators Guide](../guides/system-integrators-guide.mdx) for more information on how to use the faucet with your project. +Each SDK has integration for devnet and testnet to use the faucet. Below are a few examples, but you can +see more information on each individual [SDK's documentation](../sdks.mdx). -### Calling the faucet via Terminal +### Using the faucet in a wallet -If you are trying to call the faucet in other languages, you have two options: +Most wallets, such as [Petra](https://aptosfoundation.org/ecosystem/project/petra) or [Pontem](https://aptosfoundation.org/ecosystem/project/pontem-wallet) +will have a faucet button for devnet and testnet. See full list of [Aptos Wallets](https://aptosfoundation.org/ecosystem/projects/wallets). -1. Generate a client from -the [OpenAPI spec](https://github.com/aptos-labs/aptos-core/blob/main/crates/aptos-faucet/doc/spec.yaml). -2. Call the faucet on your own. +### Using the faucet in the Aptos CLI -For the latter, you will want to build a query similar to this: +Once you've [set up your CLI](../cli/setup-cli.mdx), you can simply call fund-with-faucet. The amount used is in Octas (1 APT = 1,000,000,000 Octas). ```bash filename="Terminal" -curl -X POST -'https://faucet.devnet.aptoslabs.com/mint?amount=10000&address=0xd0f523c9e73e6f3d68c16ae883a9febc616e484c4998a72d8899a1009e5a89d6' +aptos account fund-with-faucet --account 0xd0f523c9e73e6f3d68c16ae883a9febc616e484c4998a72d8899a1009e5a89d6 --amount 100000000 ``` -This means mint 10000 [Octas](../../network/glossary.mdx#Octa) to -address `0xd0f523c9e73e6f3d68c16ae883a9febc616e484c4998a72d8899a1009e5a89d6`. +### Using the faucet in the TypeScript SDK + +Here is an example funding the account `0xd0f523c9e73e6f3d68c16ae883a9febc616e484c4998a72d8899a1009e5a89d6` with 1 APT in Devnet. The amount used is in Octas (1 APT = 1,000,000,000 Octas). + +```ts filename="index.ts" +import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk"; + +const aptos = new Aptos(new AptosConfig({network: Network.Devnet})); +aptos.fundAccount({accountAddress: "0xd0f523c9e73e6f3d68c16ae883a9febc616e484c4998a72d8899a1009e5a89d6", amount: 100000000}); +``` +### Using the faucet in the Go SDK -### Calling the faucet: JavaScript / TypeScript +Here is an example funding the account `0xd0f523c9e73e6f3d68c16ae883a9febc616e484c4998a72d8899a1009e5a89d6` with 1 APT in Devnet. The amount used is in Octas (1 APT = 1,000,000,000 Octas). -If you are building a client in JavaScript or TypeScript, you should make use -of the [@aptos-labs/aptos-faucet-client](https://www.npmjs.com/package/@aptos-labs/aptos-faucet-client) -package. This client is generated based on the OpenAPI spec published by the -faucet service. +```go filename="index.go" +import "github.com/aptos-labs/aptos-go-sdk" -Example use: +func main() { + client, err := aptos.NewClient(aptos.LocalnetConfig) + if err != nil { + panic(err) + } -```ts filename="index.ts" -import { - AptosFaucetClient, - FundRequest, -} from "@aptos-labs/aptos-faucet-client"; - -async function callFaucet(amount: number, address: string): Promise { - const faucetClient = new AptosFaucetClient({ - BASE: "https://faucet.devnet.aptoslabs.com", - }); - const request: FundRequest = { - amount, - address, - }; - const response = await faucetClient.fund.fund({ requestBody: request }); - return response.txn_hashes; + client.Fund("0xd0f523c9e73e6f3d68c16ae883a9febc616e484c4998a72d8899a1009e5a89d6", 100000000) } ``` +### Calling the faucet: Other languages not supported by SDKs + +If you are trying to call the faucet in other languages, you have two options: + +1. Generate a client from +the [OpenAPI spec](https://github.com/aptos-labs/aptos-core/blob/main/crates/aptos-faucet/doc/spec.yaml). +2. Call the faucet on your own. + +For the latter, you will want to build a query similar to this: + +```bash filename="Terminal" +curl -X POST +'https://faucet.devnet.aptoslabs.com/mint?amount=10000&address=0xd0f523c9e73e6f3d68c16ae883a9febc616e484c4998a72d8899a1009e5a89d6' +``` + +This means mint 10000 [octas](../../network/glossary.mdx#Octa) to +address `0xd0f523c9e73e6f3d68c16ae883a9febc616e484c4998a72d8899a1009e5a89d6`. diff --git a/apps/nextra/pages/en/build/apis/fullnode-rest-api.mdx b/apps/nextra/pages/en/build/apis/fullnode-rest-api.mdx index 6337e81b9..e5f8878ed 100644 --- a/apps/nextra/pages/en/build/apis/fullnode-rest-api.mdx +++ b/apps/nextra/pages/en/build/apis/fullnode-rest-api.mdx @@ -10,10 +10,6 @@ import { Card, Cards } from '@components/index' This API - embedded into Fullnodes - provides a simple, low latency, yet low-level way of reading state and submitting transactions to the Aptos Blockchain. It also supports transaction simulation. For more advanced queries, we recommend using the [Indexer GraphQL API](../indexer.mdx). - -Also see the [System Integrators Guide](../guides/system-integrators-guide.mdx) for a thorough walkthrough of Aptos integration. - - ## Fullnode REST API Explorer @@ -86,7 +82,7 @@ View functions do not modify blockchain state when called from the API. A [View - related [Move](https://github.com/aptos-labs/aptos-core/blob/90c33dc7a18662839cd50f3b70baece0e2dbfc71/aptos-move/framework/aptos-framework/sources/coin.move#L226) code - [specification](https://github.com/aptos-labs/aptos-core/blob/90c33dc7a18662839cd50f3b70baece0e2dbfc71/api/doc/spec.yaml#L8513). -The view function operates like the [Aptos Simulation API](../guides/system-integrators-guide.mdx), +The view function operates like the Aptos simulation API, though with no side effects and an accessible output path. View functions can be called via the `/view` endpoint. Calls to view functions require the module and function names along with input type parameters and values. diff --git a/apps/nextra/pages/en/build/cli/running-a-local-network.mdx b/apps/nextra/pages/en/build/cli/running-a-local-network.mdx index fe2d8c218..4f87a4ad5 100644 --- a/apps/nextra/pages/en/build/cli/running-a-local-network.mdx +++ b/apps/nextra/pages/en/build/cli/running-a-local-network.mdx @@ -120,7 +120,7 @@ As you can see from the example output in step 4, once the local network is runn - [Indexer API](../indexer/aptos-hosted.mdx): This is a [GraphQL](https://graphql.org/) API that provides rich read access to indexed blockchain data. If you click on the URL for the Indexer API above, by default [http://127.0.0.1:8090](http://127.0.0.1:8090/), it will open the Hasura Console, a web UI that will help you query the Indexer GraphQL API. - [Transaction Stream Service](../indexer/txn-stream.mdx): This is a gRPC stream of transactions used by the Indexer API. This is only relevant to you if you are developing a [custom processor](../indexer/custom-processors.mdx). - [Postgres](https://www.postgresql.org/): This is the database that the Indexer processors write to. The Indexer API reads from this database. -- [Faucet](../guides/system-integrators-guide.mdx#integrating-with-the-faucet): You can use this to fund accounts on your local network. +- [Faucet](../apis/faucet-api.mdx): You can use this to fund accounts on your local network. If you do not want to run any of these sub-components of a network, there are flags to disable them. diff --git a/apps/nextra/pages/en/build/guides/_meta.tsx b/apps/nextra/pages/en/build/guides/_meta.tsx index 5762cfcec..1c7d9f259 100644 --- a/apps/nextra/pages/en/build/guides/_meta.tsx +++ b/apps/nextra/pages/en/build/guides/_meta.tsx @@ -43,8 +43,14 @@ export default { "key-rotation": { title: "Account Key Rotation", }, - + "---integration---": { + type: "separator", + title: "Integration Guides", + }, + exchanges: { + title: "Exchanges", + }, "system-integrators-guide": { - title: "Integrate with the Aptos Blockchain", + title: "Applications", }, }; diff --git a/apps/nextra/pages/en/build/guides/build-e2e-dapp/4-fetch-data-from-chain.mdx b/apps/nextra/pages/en/build/guides/build-e2e-dapp/4-fetch-data-from-chain.mdx index 79c7dc825..5fa424a3d 100644 --- a/apps/nextra/pages/en/build/guides/build-e2e-dapp/4-fetch-data-from-chain.mdx +++ b/apps/nextra/pages/en/build/guides/build-e2e-dapp/4-fetch-data-from-chain.mdx @@ -35,7 +35,7 @@ const aptos = new Aptos(); This will initialize a `Aptos` instance for us. -By default, `Aptos` will interact with the `devnet` network, to set up a [different network](../../guides/system-integrators-guide.mdx#choose-a-network), we can use `AptosConfig` class. +By default, `Aptos` will interact with the `devnet` network, to set up a [different network](../../../network/nodes/networks.mdx), we can use `AptosConfig` class. ```tsx filename="App.tsx" import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk"; diff --git a/apps/nextra/pages/en/build/guides/exchanges.mdx b/apps/nextra/pages/en/build/guides/exchanges.mdx new file mode 100644 index 000000000..76b26fcaa --- /dev/null +++ b/apps/nextra/pages/en/build/guides/exchanges.mdx @@ -0,0 +1,1180 @@ +--- +title: "Exchange Integration Guide" +--- + +import { Callout } from "nextra/components"; + +# Exchange Integration Guide + +This describes how to integrate Aptos and Aptos assets into an exchange. It provides +generic information for tracking balances, transferring assets, and testing the integration. + +## Overview + +This document will guide you through the following tasks to integrate with Aptos: +* Infrastructure +* Address standards +* Asset standards +* Retrieving balances +* Tracking balance changes +* Transferring assets +* Testing the integration + +## Infrastructure + +It's suggested that you run your own [full node](/network/nodes/full-node.mdx) to interact with the Aptos blockchain. +This will allow you to query the blockchain for the latest state and submit transactions. +You can also use the [Indexer](/build/apis/indexer.mdx) to query for on-chain data efficiently. + +## Address Standards + +### Addresses +A single address can be represented in three ways. We recommend you show all leading zeros, and the `0x`. Here is an example of all three representations for the framework address `0x1`: +* `0x00000000000000000000000000000001` - A full representation of 32-bytes in hex with a leading `0x`. This is preferred. +* `0x1` - The short representation of the address with a leading `0x`. This is kept around for compatibility, but preferred with all leading 0s. +* `00000000000000000000000000000001` - A full representation of 32-bytes in hex without a leading `0x`. This is kept around for compatibility, but preferred with leading 0x. + +For example SDKs will handle this parsing automatically, and we suggest you use the SDKs directly to handle it for you. + +```ts filename="example.ts" +import { AccountAddress } from "@aptos-labs/ts-sdk"; +const address = AccountAddress.from("0x1"); +address.toStringLong(); // 0x00000000000000000000000000000001 +``` + +There is additionally, Aptos Name Service (ANS) for friendly .apt names. For more information about addresses +and Aptos Names, see our page on [Accounts](../../network/blockchain/accounts). + +## Account Standards + +Accounts must exist prior to sending a transaction to the blockchain. This is done by creating an account resource, which can +be created by simply calling `0x1::aptos_account::transfer` with a zero amount to the account you want to create. Optionally, +`0x1::aptos_account::create_account` can be used to create an account with a zero balance. + +```ts filename="example.ts" +import { Aptos, Ed25519Account, Ed25519PrivateKey } from "@aptos-labs/ts-sdk"; + +const aptos = new Aptos(); +const account = new Ed25519Account({privateKey: new Ed25519PrivateKey("private key")}) +const transaction = await aptos.transferCoinTransaction({sender: account.accountAddress, recipient: "receiver address", amount: 100000000}) +const pendingTransaction = await aptos.transaction.signAndSubmitTransaction({signer: account, transaction}) +const committedTransaction = await aptos.waitForTransaction({transactionHash: pendingTransaction.hash}); +``` + +## Asset Standards + +Aptos provides two standards for fungible tokens, similar to ERC-20 tokens on Ethereum: + +* An earlier [Coin standard](/build/smart-contracts/coin.mdx) used by assets on Aptos. +* A newer [Fungible Asset Standard](/build/smart-contracts/fungible-assets.mdx) which is more featured. + +Additionally, there is a migratory period for assets from Coin to Fungible Asset standards. +We will call this from now on **migrated coins**. Migrated coins can be used interchangeably +with Fungible Asset and Coin standards. This is important to note when querying balances, to +use coin functions and not fungible asset functions. + +### Coin Standard (tl;dr) + +A **coin** has an associated contract that holds the on-chain struct that represents the coin. The coin is +represented as a struct name e.g. `0x1::aptos_coin::AptosCoin` for `APT`. + +All coins are stored in an account resource called `0x1::coin::CoinStore`. Coins must be registered +prior to using the `CoinStore`, but if using the proper functions e.g. `0x1::aptos_account::transfer` +or `0x1::aptos_account::transfer_coins`, this will be done automatically. + +Coins can be *migrated* to a fungible asset. In order to support a migrated asset, +continue calling the coin functions as will be mentioned later. + +More info can be found at: [Coin Standard](/build/smart-contracts/coin.mdx) + +### Fungible Asset Standard (tl;dr) + +A **fungible asset** has an associated metadata address that holds the metadata for the fungible asset. This is commonly called the +fa metadata address. The asset is represented as an address e.g. `0xA` for `APT`. + +All fungible assets are stored in an `object`, which is called a `fungible asset store`. + +For exchanges, the most important store is `primary_fungible_store`, which is the default store for fungible assets. +This is directly connected to an owner. From this point on in this guide, we will +only talk about supporting `primary_fungible_store` for fungible assets. + +More info can be found at: [Fungible Asset Standard](/build/smart-contracts/fungible-assets.mdx) + +## Retrieving Balances + +Retrieving current balances for assets are different for each standard. Integration is considered complete when it can handle both. + +Balances are always returned in their subunits. For example, `APT` is returned in `octas` (1e-8 APT). So, when an API +returns a balance of `100000000`, this is `1 APT`. If it returns `100` this is `0.000001 APT`. + +### Coin (and migrated coins) Balances + + + Note: This includes APT and any other coin that was migrated to a fungible + asset. + + +To retrieve the balance of a coin, or a coin that was migrated to a fungible asset, you can use +the `0x1::coin::balance(account address)` view function. This will combine the coin and coin migrated to fungible asset balances. + +```ts filename="example.ts" +import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk"; + +const config = new AptosConfig({ network: Network.TESTNET }); +const aptos = new Aptos(config); + +const coinType = "0x1::aptos_coin::AptosCoin"; +const account = "0x00000000000000000000000000000001"; +const [balanceStr] = await aptos.view<[string]>({ + payload: { + function: "0x1::coin::balance", + typeArguments: [coinType], + functionArguments: [account] + } +}); +const balance = parseInt(balanceStr, 10); +``` + +A specific ledger version (transaction height) can be provided to get the balance at that point in time. The below example shows for ledger version `1,000,000`. + +```ts filename="example.ts" +import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk"; + +const config = new AptosConfig({ network: Network.TESTNET }); +const aptos = new Aptos(config); + +const coinType = "0x1::aptos_coin::AptosCoin"; +const account = "0x00000000000000000000000000000001"; +const [balanceStr] = await aptos.view<[string]>({ + payload: { + function: "0x1::coin::balance", + typeArguments: [coinType], + functionArguments: [account], + options: { + ledgerVersion: 1_000_000 + } + } +}); +const balance = parseInt(balanceStr, 10); +``` + +### Fungible Asset Balances + +To retrieve the balance of a fungible asset, you can use +the `0x1::primary_fungible_store::balance<0x1::object::ObjectCore>(account address, fungible asset metadata address)` view function. +Note, that this will not include the balance of coins if it's a migrated coin. + +```ts filename="example.ts" +import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk"; + +const config = new AptosConfig({ network: Network.TESTNET }); +const aptos = new Aptos(config); + +const faMetadataAddress = "0xA"; +const account = "0x00000000000000000000000000000001"; +const [balanceStr] = await aptos.view<[string]>({ + payload: { + function: "0x1::primary_fungible_store::balance", + typeArguments: ["0x1::object::ObjectCore"], + functionArguments: [account, faMetadataAddress] + } +}); +const balance = parseInt(balanceStr, 10); +``` + +A specific ledger version (transaction height) can be provided to get the balance at that point in time. The below example shows for ledger version `1,000,000`. + +```ts filename="example.ts" +import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk"; + +const config = new AptosConfig({ network: Network.TESTNET }); +const aptos = new Aptos(config); + +const faMetadataAddress = "0xA"; +const account = "0x00000000000000000000000000000001"; +const [balanceStr] = await aptos.view<[string]>({ + payload: { + function: "0x1::primary_fungible_store::balance", + typeArguments: ["0x1::object::ObjectCore"], + functionArguments: [account, faMetadataAddress] + }, + options: { + ledgerVersion: 1_000_000 + } +}); +const balance = parseInt(balanceStr, 10); +``` + +## Tracking Balance Changes + +Balance changes can be queried in one of two ways: +1. By watching for events that change the balance for each transaction. +2. By querying the indexer for indexed balance change events. + +In the past, it was able to use the `events` endpoint for an account to get the +transactions that changed the balance. This is still possible, but will be deprecated +in the future, and is not recommended for new integrations. + +### Coin Balance Changes + +Coin balances are tracked as two items, write set changes, and events. Write set +changes are end state of the coin balance, and events are the events that are +emitted when a coin is withdrawn or deposited. + +Here is an [example of a coin transfer](https://explorer.aptoslabs.com/txn/1747361321?network=mainnet). +The coin transfer can be tracked as an individual transaction +[here](https://fullnode.mainnet.aptoslabs.com/v1/transactions/by_version/1747361321) +from the REST API. + +We'll break it down into a few parts: + +1. The general transaction details tell information about the transaction. The +most important thing here is the transaction version is `1747361321`. This gives +us total order of all transactions on the blockchain. Think of it like block +height, but for transactions. +
+ Transaction Details + ```json + { + "version": "1747361321", + "hash": "0x7c56ad56c7d02bb11887e535b9f1b221626d5b0d4cb5a1ffbadc358c1db515ea", + "state_change_hash": "0xc901b5e9e0965201e8205977720d7dea8a3709ee0d818fd5ec752cac13eaf18a", + "event_root_hash": "0x0077cb7df9db9ee7194c489db177fe9a325bcf3f1309ea99ed934085e5592041", + "state_checkpoint_hash": null, + "gas_used": "999", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "0xb531e918441ff0a37b49856e0f1b80c329146461582287cf9788964d25e31a68", + } + ``` +
+2. The Write set `changes` are the end state of the transaction. It shows all +resources that were modified by the transaction, and what it's final state was. + +In this case, we only care about coin store changes. + +
+Coin Store Changes +```json + "changes": [ + { + "address": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", + "state_key_hash": "0xb2bfa7198457291a0e582b912be2bf8577feff08e352c9f16935a55ebd202dcc", + "data": { + "type": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": { + "coin": { + "value": "903837250" + }, + "deposit_events": { + "counter": "10", + "guid": { + "id": { + "addr": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", + "creation_num": "2" + } + } + }, + "frozen": false, + "withdraw_events": { + "counter": "52485", + "guid": { + "id": { + "addr": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", + "creation_num": "3" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28", + "state_key_hash": "0xa45b7cfe18cc0ef1d6588f0f548a6a6a260d5e6bbab174507ed40cd21b7bd082", + "data": { + "type": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": { + "coin": { + "value": "10" + }, + "deposit_events": { + "counter": "1", + "guid": { + "id": { + "addr": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28", + "creation_num": "2" + } + } + }, + "frozen": false, + "withdraw_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28", + "creation_num": "3" + } + } + } + } + }, + "type": "write_resource" + }], +``` +
+ +3. Events are the events that were emitted by the transaction. In this case, we +only care about the `0x1::coin::deposit` and `0x1::coin::withdraw` events. + +The Coin deposit event is emitted when coins are deposited into an account. The +account's balance will increase by that amount in the field `data.amoount`. To +determine the matching asset, you must match the `guid` in the `deposit_events` +to the `guid` in the `changes` section for a `CoinStore`. + +
+ Coin Deposit Event + ```json + { + "events": [{ + "guid": { + "creation_number": "2", + "account_address": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28" + }, + "sequence_number": "0", + "type": "0x1::coin::DepositEvent", + "data": { + "amount": "10" + } + }] + } + ``` +
+ +The Coin withdraw event is emitted when coins are withdrawn from an account. The +account's balance will decrease by that amount in the field `data.amount`. To +determine the matching asset, you must match the `guid` in the `deposit_events` +to the `guid` in the `changes` section for a `CoinStore`. + +
+ Coin Withdraw Event + ```json + { + "events": [{ + "guid": { + "creation_number": "3", + "account_address": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0" + }, + "sequence_number": "52484", + "type": "0x1::coin::WithdrawEvent", + "data": { + "amount": "10" + } + }] + } + ``` +
+ +4. Gas usage only is tracked for APT. There is no direct event for tracking gas, +but it can be calculated from the transaction. Using the `gas_used` field, and +the `gas_unit_price` field, you can calculate the total gas used. In this case, +the `gas_used` is `999` and the `gas_unit_price` is `100`, so the total gas deducted +from the sender(`0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0`) +is `999 * 100 = 99900 subunits` Remember that the subunits are used here. The +value in the gas token `APT` is `0.00099900 APT`. + + +
+ Gas Information +```json + { + "gas_used": "999", + "max_gas_amount": "100000", + "gas_unit_price": "100", + "sender": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", +} +``` +
+ + +5. Overall, you need both the events and the changes to determine the amount transferred +of the account. The final balances will show in the changes alone. If you watch +all of these events, you will be able to handle all possible transactions. Below +is the full example of the transaction response. + +
+ Full Response + ```json + { + "version": "1747361321", + "hash": "0x7c56ad56c7d02bb11887e535b9f1b221626d5b0d4cb5a1ffbadc358c1db515ea", + "state_change_hash": "0xc901b5e9e0965201e8205977720d7dea8a3709ee0d818fd5ec752cac13eaf18a", + "event_root_hash": "0x0077cb7df9db9ee7194c489db177fe9a325bcf3f1309ea99ed934085e5592041", + "state_checkpoint_hash": null, + "gas_used": "999", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "0xb531e918441ff0a37b49856e0f1b80c329146461582287cf9788964d25e31a68", + "changes": [ + { + "address": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", + "state_key_hash": "0xb2bfa7198457291a0e582b912be2bf8577feff08e352c9f16935a55ebd202dcc", + "data": { + "type": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": { + "coin": { + "value": "903837250" + }, + "deposit_events": { + "counter": "10", + "guid": { + "id": { + "addr": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", + "creation_num": "2" + } + } + }, + "frozen": false, + "withdraw_events": { + "counter": "52485", + "guid": { + "id": { + "addr": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", + "creation_num": "3" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", + "state_key_hash": "0xa3f2635d084b3cc01ae545c96ee15901549dab594363a46bf18e3d575c83102d", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", + "coin_register_events": { + "counter": "1", + "guid": { + "id": { + "addr": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", + "creation_num": "0" + } + } + }, + "guid_creation_num": "4", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "104628", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28", + "state_key_hash": "0xa45b7cfe18cc0ef1d6588f0f548a6a6a260d5e6bbab174507ed40cd21b7bd082", + "data": { + "type": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": { + "coin": { + "value": "10" + }, + "deposit_events": { + "counter": "1", + "guid": { + "id": { + "addr": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28", + "creation_num": "2" + } + } + }, + "frozen": false, + "withdraw_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28", + "creation_num": "3" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28", + "state_key_hash": "0xba04f5a13812778031f67322e9801be65a846224e46f1360a6008402fcd0e0e0", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28", + "coin_register_events": { + "counter": "1", + "guid": { + "id": { + "addr": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28", + "creation_num": "0" + } + } + }, + "guid_creation_num": "4", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "0", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "0x6e4b28d40f98a106a65163530924c0dcb40c1349d3aa915d108b4d6cfc1ddb19", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "value": "0x9f9835f429758d010000000000000000", + "data": null, + "type": "write_table_item" + } + ], + "sender": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0", + "sequence_number": "104627", + "max_gas_amount": "100000", + "gas_unit_price": "100", + "expiration_timestamp_secs": "1727826277", + "payload": { + "function": "0x1::aptos_account::transfer", + "type_arguments": [], + "arguments": [ + "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28", + "10" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0xfd448fada2bac29c5f3213277e001ca8851d5644578e79484b0426c41357a457", + "signature": "0x40d8a6ee9150aa5736bee23ce1b1b851790bc0aa7e2485c0760d5808027040a2ef4170b88962867b045197576c5e89a4c640bf43586e6b3ead2b510b59acc20a", + "type": "ed25519_signature" + }, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28" + }, + "sequence_number": "0", + "type": "0x1::account::CoinRegisterEvent", + "data": { + "type_info": { + "account_address": "0x1", + "module_name": "0x6170746f735f636f696e", + "struct_name": "0x4170746f73436f696e" + } + } + }, + { + "guid": { + "creation_number": "3", + "account_address": "0x559d4f690c683fca7c539237aa8dc4c6ec09886b7016bf66f2cdeffef55468f0" + }, + "sequence_number": "52484", + "type": "0x1::coin::WithdrawEvent", + "data": { + "amount": "10" + } + }, + { + "guid": { + "creation_number": "2", + "account_address": "0x5d6233bb8d7f8bd714af196339e9fb3104c9d66f38867b2a0585c4f7b9d04d28" + }, + "sequence_number": "0", + "type": "0x1::coin::DepositEvent", + "data": { + "amount": "10" + } + }, + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "6", + "io_gas_units": "5", + "storage_fee_octas": "98800", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "999" + } + } + ], + "timestamp": "1727825677775812", + "type": "user_transaction" + } + ``` +
+ + +### Fungible Asset Balance Changes + +For fungible assets, the balance changes are tracked in the `primary_fungible_store`. +The primary fungible store address is deterministic, and will always be tracked by +the owner of the store. + +An example: https://api.mainnet.aptoslabs.com/v1/transactions/by_version/1750174030 + +There are a few steps when tracking fungible assets: + +1. There will be two types of events for fungible assets. `0x1::fungible_asset::Deposit` and `0x1::fungible_asset::Withdraw`. + +`Withdraw` events are similar to the coin events, where the balance will decrease by the amount in the `data.amount` field. +And similarly `Deposit` events will increase the balance by the amount in the `data.amount` field. + +Note that, I've omitted the sequence number, and GUID fields, as they do not apply to these events. + +Each event has a `store` field, which in this case is `0x8a9d57692a9d4deb1680eaf107b83c152436e10f7bb521143fa403fa95ef76a`. +This is the address of the `FungibleStore` for the asset, where the balance is stored. Note this, for the next step. + +
+ Fungible Asset Events +```json +{ + "events": [ + { + "type": "0x1::fungible_asset::Withdraw", + "data": { + "amount": "1", + "store": "0x8a9d57692a9d4deb1680eaf107b83c152436e10f7bb521143fa403fa95ef76a" + } + }, + { + "type": "0x1::fungible_asset::Deposit", + "data": { + "amount": "1", + "store": "0x8a9d57692a9d4deb1680eaf107b83c152436e10f7bb521143fa403fa95ef76a" + } + } + ] +} +``` +
+ +2. Next, we take a look at the `0x1::fungible_asset::FungibleStore` changes. This +will show the end state of the balance for the fungible asset. The balance is in +the `data.balance` field. The `address` field will match the `store` field from +the events. The identifier of the fungible asset, is the `metadata` field. It +is the address of the `metadata` for the fungible asset. + +Additionally, to figure out the actual owner of the assets, you will need to look +at the owner of the store. In this case, you will need the `0x1::object::ObjectCore`, where +the `address` field matches the `store` field from the events. The `owner` field +will show the asset owner's address. + +
+ Fungible Asset Changes +```json +{ + "changes":[ + { + "address": "0x8a9d57692a9d4deb1680eaf107b83c152436e10f7bb521143fa403fa95ef76a", + "state_key_hash": "0x5b587931247dd5b43874ab29c3305c0ee7d26e7571fed3aea409375530e3a62c", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "126691270443", + "frozen": false, + "metadata": { + "inner": "0x2ebb2ccac5e027a87fa0e2e5f656a3a4238d6a48d93ec9b610d570fc0aa0df12" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x8a9d57692a9d4deb1680eaf107b83c152436e10f7bb521143fa403fa95ef76a", + "state_key_hash": "0x5b587931247dd5b43874ab29c3305c0ee7d26e7571fed3aea409375530e3a62c", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842628", + "owner": "0xc67545d6f3d36ed01efc9b28cbfd0c1ae326d5d262dd077a29539bcee0edce9e", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x8a9d57692a9d4deb1680eaf107b83c152436e10f7bb521143fa403fa95ef76a", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + } + ] +} +``` +
+ + +### Coins migrated to Fungible Asset Balance Changes + +For coins migrated to fungible assets, it is just simply tracking of the two above. +A coin migrated to a fungible asset will have both the coin store changes and the +primary fungible asset store changes. The amounts would need to be aggregated +together, and otherwise, handled as a coin. + +The Fungible asset metadata address is the hash of the coin type and 0xA + +``` +address = sha3_256(0xA | coin_type) +``` + +Here is an example of a migrated coin with APT: https://api.mainnet.aptoslabs.com/v1/transactions/by_version/1642580695 +
+ Full response + ```json + { + "version": "1642580695", + "hash": "0xe67ba1c4242d5c1de42eb8419558c4edf2318e185a3940a00f4150b519d06508", + "state_change_hash": "0x07c5ec97afdf731c2778fccb37fe209369b28dcf6dcf11c3cf13b83c962f7f96", + "event_root_hash": "0xad349cbea90bef601dfae9df822f5698af296951fc5f94359fcacc1e69e9fa3d", + "state_checkpoint_hash": null, + "gas_used": "545", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "0x88e81bde70f32a86e46b288a917a44b2868a46973fac7fad16b5e780f48b0e67", + "changes": [ + { + "address": "0xa", + "state_key_hash": "0x1db5441d8fa4229c5844f73fd66da4ad8176cb8793d8b3a7f6ca858722030043", + "data": { + "type": "0x1::coin::PairedCoinType", + "data": { + "type": { + "account_address": "0x1", + "module_name": "0x6170746f735f636f696e", + "struct_name": "0x4170746f73436f696e" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xa", + "state_key_hash": "0x1db5441d8fa4229c5844f73fd66da4ad8176cb8793d8b3a7f6ca858722030043", + "data": { + "type": "0x1::coin::PairedFungibleAssetRefs", + "data": { + "burn_ref_opt": { + "vec": [ + { + "metadata": { + "inner": "0xa" + } + } + ] + }, + "mint_ref_opt": { + "vec": [ + { + "metadata": { + "inner": "0xa" + } + } + ] + }, + "transfer_ref_opt": { + "vec": [ + { + "metadata": { + "inner": "0xa" + } + } + ] + } + } + }, + "type": "write_resource" + }, + { + "address": "0xa", + "state_key_hash": "0x1db5441d8fa4229c5844f73fd66da4ad8176cb8793d8b3a7f6ca858722030043", + "data": { + "type": "0x1::fungible_asset::ConcurrentSupply", + "data": { + "current": { + "max_value": "340282366920938463463374607431768211455", + "value": "47948384" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xa", + "state_key_hash": "0x1db5441d8fa4229c5844f73fd66da4ad8176cb8793d8b3a7f6ca858722030043", + "data": { + "type": "0x1::fungible_asset::Metadata", + "data": { + "decimals": 8, + "icon_uri": "", + "name": "Aptos Coin", + "project_uri": "", + "symbol": "APT" + } + }, + "type": "write_resource" + }, + { + "address": "0xa", + "state_key_hash": "0x1db5441d8fa4229c5844f73fd66da4ad8176cb8793d8b3a7f6ca858722030043", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": true, + "guid_creation_num": "1125899906842625", + "owner": "0x1", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0xa", + "state_key_hash": "0x1db5441d8fa4229c5844f73fd66da4ad8176cb8793d8b3a7f6ca858722030043", + "data": { + "type": "0x1::primary_fungible_store::DeriveRefPod", + "data": { + "metadata_derive_ref": { + "self": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x7ed92ce166e251fc133f6b4d46a6b41307962e3b6864c2231110b3808648188", + "state_key_hash": "0x5ce89e323a23fb5570694dfb687d474d44563638c5ef774a2364d8347f5732b8", + "data": { + "type": "0x1::coin::MigrationFlag", + "data": { + "dummy_field": false + } + }, + "type": "write_resource" + }, + { + "address": "0x7ed92ce166e251fc133f6b4d46a6b41307962e3b6864c2231110b3808648188", + "state_key_hash": "0x5ce89e323a23fb5570694dfb687d474d44563638c5ef774a2364d8347f5732b8", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "37949184", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x7ed92ce166e251fc133f6b4d46a6b41307962e3b6864c2231110b3808648188", + "state_key_hash": "0x5ce89e323a23fb5570694dfb687d474d44563638c5ef774a2364d8347f5732b8", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0xa746e980ae21949a4f084db7403430f00bce3c9a1da4101ffcf0bf45ebd35e7e", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x7ed92ce166e251fc133f6b4d46a6b41307962e3b6864c2231110b3808648188", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x8a4613c356c21a45045e06dcc404bfee363aabd65a774d4d43defd71289239b2", + "state_key_hash": "0x7c2d6e31d4ac5bbf93e19412437c0c288766b240674f71f457b9e3ef68be5003", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "10000", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x8a4613c356c21a45045e06dcc404bfee363aabd65a774d4d43defd71289239b2", + "state_key_hash": "0x7c2d6e31d4ac5bbf93e19412437c0c288766b240674f71f457b9e3ef68be5003", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x5", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x8a4613c356c21a45045e06dcc404bfee363aabd65a774d4d43defd71289239b2", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0xa746e980ae21949a4f084db7403430f00bce3c9a1da4101ffcf0bf45ebd35e7e", + "state_key_hash": "0xfb7c1f2762da89f00a222f93bd771b478edb4361475c4a518178564be8616dd6", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xa746e980ae21949a4f084db7403430f00bce3c9a1da4101ffcf0bf45ebd35e7e", + "coin_register_events": { + "counter": "14", + "guid": { + "id": { + "addr": "0xa746e980ae21949a4f084db7403430f00bce3c9a1da4101ffcf0bf45ebd35e7e", + "creation_num": "0" + } + } + }, + "guid_creation_num": "44", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa746e980ae21949a4f084db7403430f00bce3c9a1da4101ffcf0bf45ebd35e7e", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "52", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa746e980ae21949a4f084db7403430f00bce3c9a1da4101ffcf0bf45ebd35e7e", + "sequence_number": "51", + "max_gas_amount": "817", + "gas_unit_price": "100", + "expiration_timestamp_secs": "1724196316", + "payload": { + "function": "0x1::primary_fungible_store::transfer", + "type_arguments": [ + "0x1::fungible_asset::Metadata" + ], + "arguments": [ + { + "inner": "0xa" + }, + "0x5", + "10000" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x330e75a102e37270b788caee8dd819e5badedd5fa17fe9f72017732e9bb98c60", + "signature": "0xd4666df2887cf2d8192230e4a03d842ea75a86ffbc46a9a16a9baede6ff646c6b2bcafc524d3a4a7a66c223b5db576beb5cfefbd549620e69097c0a364c7a800", + "type": "ed25519_signature" + }, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::fungible_asset::Withdraw", + "data": { + "amount": "10000", + "store": "0x7ed92ce166e251fc133f6b4d46a6b41307962e3b6864c2231110b3808648188" + } + }, + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::fungible_asset::Deposit", + "data": { + "amount": "10000", + "store": "0x8a4613c356c21a45045e06dcc404bfee363aabd65a774d4d43defd71289239b2" + } + }, + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::fungible_asset::Withdraw", + "data": { + "amount": "54500", + "store": "0x7ed92ce166e251fc133f6b4d46a6b41307962e3b6864c2231110b3808648188" + } + }, + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "6", + "io_gas_units": "7", + "storage_fee_octas": "53240", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "545" + } + } + ], + "timestamp": "1724196287102837", + "type": "user_transaction" + } + ``` +
+ +## Transferring Assets + +### Coin (or migrated coin) Transfers + +We suggest you use `0x1::aptos_account::transfer_coins(receiver address, amount)` for transferring coins. It will +register the coin if it hasn't been registered yet, and create the associated account if it hasn't been created yet. +This will continue to work with any coins that were migrated to a fungible asset, including APT. + +Coins can be transferred in the following ways: +* [`0x1::aptos_account::transfer_coins(receiver address, amount)`](https://github.com/aptos-labs/aptos-core/blob/main/aptos-move/framework/aptos-framework/sources/aptos_account.move#L108-L112) - Transfer a coin to another account. +* [`0x1::aptos_account::batch_transfer_coins(receiver addresses, amounts)`](https://github.com/aptos-labs/aptos-core/blob/main/aptos-move/framework/aptos-framework/sources/aptos_account.move#L93-L106) - Transfer a coin to multiple accounts. +* [`0x1::aptos_account::transfer(receiver address, amount)`](https://github.com/aptos-labs/aptos-core/blob/main/aptos-move/framework/aptos-framework/sources/aptos_account.move#L74-L91) - Transfer specifically APT to another account. + +{/* TODO examples */} + +### Fungible Asset Transfers + +We suggest you use `0x1::primary_fungible_store::transfer<0x1::object::ObjectCore>(receiver address, amount)` for transferring fungible assets. +It will send the associated fungible asset, and create a primary store for the asset if it hasn't been created yet. + +{/* TODO examples */} + + + Note: This will not create an account for the user if it hasn't been created + yet. You will need to call + `0x1::aptos_account::create_account(account address)` to create the account + before the user can + submit transactions. + + +{ /* TODO Staking some other day */ } + +## Testing + +In order to check that everything is working correctly, we've provided these checks. + +### Balance Checks + +To test balance checks, you can check the balance for the account `0x5` for the asset `0x1::aptos_coin::AptosCoin`. +The balance should show `0.002 APT`, where 0.001 APT is a coin, and 0.001 APT is a migrated coin (fungible asset). + +If your balance is not correct, see [Coin and Migrated Coin Balances](#coin-and-migrated-coin-balances) for more information. + +### Balance Change / Transfer Checks + +#### Check Coin Transfer + +To test a transfer, create a transaction to transfer 0.001 APT to another account. +The transaction should be successful, and the balance should be updated, where +the balance is 0.001 APT smaller and minus the gas cost associated. + +#### Check Fungible Asset Transfer + +To test a transfer, you can fund an account with the fungible asset here https://test-token-faucet.vercel.app/ +and then transfer the fungible asset to another account. The balance should be updated +according to the change, and you should be able to track the mint on the website. + + +## FAQ + +### What is the finality of a transaction? + +Aptos uses a BFT consensus algorithm, so transactions are finalized immediately +after committing to the blockchain. + +### What is the transaction fee on a transaction? + +Transaction fees are variable, but for most cases here are fixed. Check out +[simulating transactions](/network/blockchain/gas-txn-fee#estimating-gas-consumption-via-simulation) +to get an idea of the fee. diff --git a/apps/nextra/pages/en/build/guides/system-integrators-guide.mdx b/apps/nextra/pages/en/build/guides/system-integrators-guide.mdx index e6869de03..79264ae4b 100644 --- a/apps/nextra/pages/en/build/guides/system-integrators-guide.mdx +++ b/apps/nextra/pages/en/build/guides/system-integrators-guide.mdx @@ -4,7 +4,12 @@ title: "Application Integration Guide" import { Callout } from "nextra/components"; -# Integrate with the Aptos Blockchain +# Application Integration Guide + + + This guide is currently in progress of being replaced. Please check out the [exchange integration guide](./exchanges.mdx) + for more up-to-date information. + If you provide blockchain services to your customers and wish to add the Aptos blockchain to your platform, then this guide is for you. This system integrators @@ -32,79 +37,10 @@ specific account, i.e., withdraws and deposits. In order to get started you'll need to select a network and pick your set of tools. There are also a handful of SDKs to help accelerate development. -### Choose a network - -There are four well-supported networks for integrating with the Aptos -blockchain: - -1. [Localnet](http://127.0.0.1:8080) -- our standalone tool for local -development against a known version of the codebase with no external network. -2. [Devnet](https://api.devnet.aptoslabs.com/v1/spec#/) -- a shared resource for -the community, data resets weekly, weekly update from aptos-core main branch. -3. [Testnet](https://api.testnet.aptoslabs.com/v1/spec#/) -- a shared resource -for the community, data will be preserved, network configuration will mimic -Mainnet. -4. [Mainnet](https://api.mainnet.aptoslabs.com/v1/spec#/) -- a production -network with real assets. - -See [Aptos Blockchain Networks](../../network/nodes/networks.mdx) for full details on each -environment. - -### Run a localnet - -There are two options for running a localnet: - -- [Install the Aptos CLI](../cli.mdx) and 2) run -a [local development network](../cli/running-a-local-network.mdx). -This path is useful for developing on the Aptos blockchain, debugging Move -contracts, and testing node operations. This will provide a fully featured -local development environment including a single node network, a node REST -API, an Indexer API, and a faucet. -- Directly [run a localnet](../../network/nodes/localnet/run-a-localnet.mdx) using either -the [Aptos-core source code](../../network/nodes/localnet/run-a-localnet.mdx). -These paths are useful for testing changes to the Aptos-core codebase or -framework, or for building services on top of the Aptos blockchain, -respectively. - -Either of these methods will expose -a [REST API service](../apis/fullnode-rest-api.mdx) at `http://127.0.0.1:8080` -and a Faucet API service at `http://127.0.0.1:8000` for option 1 run a localnet -or `http://127.0.0.1:8081` for option 2 install the Aptos CLI. The applications -will output the location of the services. - -### Production network access -{/* TODO: Make into a table */} -#### Devnet - * [REST API](https://api.devnet.aptoslabs.com/v1) - * [REST API Spec](https://api.devnet.aptoslabs.com/v1/spec#) - * [Indexer API](https://api.devnet.aptoslabs.com/v1/graphql) - * [Faucet API](https://faucet.devnet.aptoslabs.com) - * [Indexer GraphQL](https://cloud.hasura.io/public/graphiql?endpoint=https://api.devnet.aptoslabs.com/v1/graphql) - -### Testnet - * [REST API](https://api.testnet.aptoslabs.com/v1) - * [REST API Spec](https://api.testnet.aptoslabs.com/v1/spec#) - * [Indexer API](https://api.testnet.aptoslabs.com/v1/graphql) - * [Faucet API](https://faucet.testnet.aptoslabs.com) - * [Indexer GraphQL](https://cloud.hasura.io/public/graphiql?endpoint=https://api.testnet.aptoslabs.com/v1/graphql) - -### Mainnet - * [REST API](https://api.mainnet.aptoslabs.com/v1) - * [REST API Spec](https://api.mainnet.aptoslabs.com/v1/spec#) - * [Indexer API](https://api.mainnet.aptoslabs.com/v1/graphql) - * [Indexer GraphQL](https://cloud.hasura.io/public/graphiql?endpoint=https://api.mainnet.aptoslabs.com/v1/graphql) - ### SDKs and tools -Aptos currently provides four SDKs: - -1. [Typescript](../sdks/ts-sdk.mdx) -2. [Python](../sdks/python-sdk.mdx) -3. [Rust](../sdks/rust-sdk.mdx) -4. [.NET](../sdks/dotnet-sdk.mdx) -5. [Go SDK](../sdks/go-sdk.mdx) -6. [Unity](../sdks/unity-sdk.mdx) - +Aptos has multiple SDKs across many different languages and platforms, please +check out [SDKs](../sdks.mdx) for more information. Almost all developers will benefit from exploring the CLI. [Using the CLI](../cli.mdx) demonstrates how the CLI can be used to create @@ -170,42 +106,15 @@ HTTP headers. This will return a transaction submission result that, if successful, contains a transaction hash in the `hash` [field](https://github.com/aptos-labs/aptos-core/blob/9b85d41ed8ef4a61a9cd64f9de511654fcc02024/ecosystem/python/sdk/aptos_sdk/client.py#L138). -#### JSON-encoded transactions - -JSON-encoded transactions can be generated via -the [REST API](https://api.devnet.aptoslabs.com/v1/spec#/), following these -steps: - -1. First construct an appropriate JSON payload for -the `/transactions/encode_submission` endpoint as demonstrated in -the [Python SDK](https://github.com/aptos-labs/aptos-core/blob/b0fe7ea6687e9c180ebdbac8d8eb984d11d7e4d4/ecosystem/python/sdk/aptos_sdk/client.py#L128). -2. The output of the above contains an object containing a `message` that must -be signed with the sender’s private key locally. -3. Extend the original JSON payload with the signature information and post it -to -the `/transactions` [endpoint](https://github.com/aptos-labs/aptos-core/blob/b0fe7ea6687e9c180ebdbac8d8eb984d11d7e4d4/ecosystem/python/sdk/aptos_sdk/client.py#L142). -This will return a transaction submission result that, if successful, -contains a transaction hash in -the `hash` [field](https://github.com/aptos-labs/aptos-core/blob/b0fe7ea6687e9c180ebdbac8d8eb984d11d7e4d4/ecosystem/python/sdk/aptos_sdk/client.py#L145). - -JSON-encoded transactions allow for rapid development and support seamless ABI -conversions of transaction arguments to native types. However, most system -integrators prefer to generate transactions within their own tech stack. Both -the [TypeScript SDK](https://github.com/aptos-labs/aptos-core/blob/9b85d41ed8ef4a61a9cd64f9de511654fcc02024/ecosystem/typescript/sdk/src/aptos_client.ts#L259) -and [Python SDK](https://github.com/aptos-labs/aptos-core/blob/b0fe7ea6687e9c180ebdbac8d8eb984d11d7e4d4/ecosystem/python/sdk/aptos_sdk/client.py#L100) -support generating BCS transactions. - ### Types of transactions Within a given transaction, the target of execution can be one of two types: -- An entry point (formerly known as script function) -- A script (payload) +- An entry function +- A Move script -Both [Python](https://github.com/aptos-labs/aptos-core/blob/3973311dac6bb9348bfc81cf983c2a1be11f1b48/ecosystem/python/sdk/aptos_sdk/client.py#L256) -and [TypeScript](https://github.com/aptos-labs/aptos-core/blob/3973311dac6bb9348bfc81cf983c2a1be11f1b48/ecosystem/typescript/sdk/src/aptos_client.test.ts#L93) -support the generation of transactions that target entry points. This guide -points out many of those entry points, such as `aptos_account::transfer` +All official SDKs support the generation of transactions that target entry functions. This guide +points out many of those entry functions, such as `aptos_account::transfer` and `aptos_account::create_account`. Most basic operations on the Aptos blockchain should be available via entry @@ -217,8 +126,7 @@ example [Move script](https://github.com/aptos-labs/aptos-core/tree/main/aptos-m that uses a MultiAgent transaction to extract funds from two accounts and deposit them into two other accounts. This is a [Python example](https://github.com/aptos-labs/aptos-python-sdk/blob/main/examples/transfer_two_by_two.py) -that uses the bytecode generated by compiling that script. Currently, there is -limited support for script payloads in TypeScript. +that uses the bytecode generated by compiling that script. ### Status of a transaction @@ -231,6 +139,8 @@ A reasonable strategy for submitting transactions is to limit their lifetime to several seconds after that time has elapsed. If there is no commitment on-chain, the transaction was likely discarded. +All SDKs support this automatically for waiting for transactions. + ### Testing transactions or transaction pre-execution To facilitate evaluation of transactions as well as gas estimation, Aptos @@ -359,60 +269,46 @@ and [`aptos_account::transfer`](https://github.com/aptos-labs/aptos-core/blob/88 for Aptos coins. - It is important to note that if an account has not registered a `CoinStore` + It is important to note that if an account has not registered a + `CoinStore` for a given `T`, then any transfer of type `T` to that account will fail. ### Current balance for a coin -The current balance for a `Coin` where `T` is the Aptos coin is available at -the account resources URL: - ``` - https://{rest_api_server}/accounts/{address}/resource/0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin> - ``` - The balance is stored within `coin::amount`. The resource also contains the - total number of deposit and withdraw events, and the `counter` value - within `deposit_events` and `withdraw_events`, respectively. - ```json - { - "type": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": { - "coin": { - "value": "3927" - }, - "deposit_events": { - "counter": "1", - "guid": { - "id": { - "addr": "0xcb2f940705c44ba110cd3b4f6540c96f2634938bd5f2aabd6946abf12ed88457", - "creation_num": "2" - } - } - }, - "withdraw_events": { - "counter": "1", - "guid": { - "id": { - "addr": "0xcb2f940705c44ba110cd3b4f6540c96f2634938bd5f2aabd6946abf12ed88457", - "creation_num": "3" - } - } - } - } +To retrieve the balance of a coin, or a coin that was migrated to a fungible asset, you can use +the `0x1::coin::balance(account address)` view function. This will combine the coin and coin migrated to fungible asset balances. + +```ts filename="example.ts" +import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk"; + +const config = new AptosConfig({ network: Network.TESTNET }); +const aptos = new Aptos(config); + +const coinType = "0x1::aptos_coin::AptosCoin"; +const account = "0x00000000000000000000000000000001"; +const [balanceStr] = await aptos.view<[string]>({ + payload: { + function: "0x1::coin::balance", + typeArguments: [coinType], + functionArguments: [account] } - ``` - ### Querying transactions +}); +const balance = parseInt(balanceStr, 10); +``` - In Aptos, each transaction is committed as a distinct version to the - blockchain. This allows for the convenience of sharing committed transactions - by their version number; to do so, query: - `https://{rest_server_api}/transactions/by_version/{version}` +### Querying transactions - Transactions submitted by an account can also be queried via the following URL - where the `sequence_number` matches the sequence number of the transaction: - `https://{rest_server_api}/account/{address}/transactions?start={sequence_number}&limit=1` +In Aptos, each transaction is committed as a distinct version to the +blockchain. This allows for the convenience of sharing committed transactions +by their version number; to do so, query: +`https://{rest_server_api}/transactions/by_version/{version}` - A transfer transaction would appear as follows: +Transactions submitted by an account can also be queried via the following URL +where the `sequence_number` matches the sequence number of the transaction: +`https://{rest_server_api}/account/{address}/transactions?start={sequence_number}&limit=1` + +A transfer transaction would appear as follows: ```json { @@ -493,58 +389,58 @@ the account resources URL: } ``` - Here is a breakdown of the information in a transaction: +Here is a breakdown of the information in a transaction: - `version` indicates the globally unique identifier for this transaction, its - ordered position in all the committed transactions on the blockchain +ordered position in all the committed transactions on the blockchain - `sender` is the account address of the entity that submitted the transaction - `gas_used` is the units paid for executing the transaction - `success` and `vm_status` indicate whether the transaction successfully - executed and any reasons why it might not have +executed and any reasons why it might not have - `changes` include the final values for any state resources that have been - modified during the execution of the transaction +modified during the execution of the transaction - `events` contain all the events emitted during the transaction execution - `timestamp` is the near real-time timestamp of the transaction's execution - If `success` is false, then `vm_status` will contain an error code or message - that resulted in the transaction failing to succeed. When `success` is - false, `changes` will be limited to gas deducted from the account and the - sequence number incrementing. There will be no `events`. - - Each event in `events` is differentiated by a `key`. The `key` is derived from - the `guid` in `changes`. Specifically, the `key` is a 40-byte hex string where - the first eight bytes (or 16 characters) are the little-endian representation - of the `creation_num` in the `guid` of the `changes` event, and the remaining - characters are the account address. - - As events do not dictate what emitted them, it is imperative to track the path - in `changes` to determine the source of an event. In particular, - each `CoinStore` has both a `WithdrawEvent` and a `DepositEvent`, based - upon the type of coin. In order to determine which coin type is used in a - transaction, an indexer can compare the `guid::creation_num` in a `changes` - event combined with the address to the `key` for events in `events`. - - Using the above example, `events[1].guid` is equivalent - to `changes[0].data.data.deposit_events.guid`, which - is +If `success` is false, then `vm_status` will contain an error code or message +that resulted in the transaction failing to succeed. When `success` is +false, `changes` will be limited to gas deducted from the account and the +sequence number incrementing. There will be no `events`. + +Each event in `events` is differentiated by a `key`. The `key` is derived from +the `guid` in `changes`. Specifically, the `key` is a 40-byte hex string where +the first eight bytes (or 16 characters) are the little-endian representation +of the `creation_num` in the `guid` of the `changes` event, and the remaining +characters are the account address. + +As events do not dictate what emitted them, it is imperative to track the path +in `changes` to determine the source of an event. In particular, +each `CoinStore` has both a `WithdrawEvent` and a `DepositEvent`, based +upon the type of coin. In order to determine which coin type is used in a +transaction, an indexer can compare the `guid::creation_num` in a `changes` +event combined with the address to the `key` for events in `events`. + +Using the above example, `events[1].guid` is equivalent +to `changes[0].data.data.deposit_events.guid`, which +is ```json {"addr": "0x5098df8e7969b58ab3bd2d440c6203f64c60a1fd5c08b9d4abe6ae4216246c3e", "creation_num": "2"} ``` - - The `key` field will be going away in favor of `guid` - + + The `key` field will be going away in favor of `guid` + - ### Querying events +### Querying events - Aptos provides clear and canonical events for all withdraw and deposit of - coins. This can be used in coordination with the associated transactions to - present to a user the change of their account balance over time, when that - happened, and what caused it. With some amount of additional parsing, metadata - such as the transaction type and the other parties involved can also be shared. +Aptos provides clear and canonical events for all withdraw and deposit of +coins. This can be used in coordination with the associated transactions to +present to a user the change of their account balance over time, when that +happened, and what caused it. With some amount of additional parsing, metadata +such as the transaction type and the other parties involved can also be shared. - Query events by handle - URL: `https://{rest_api_server}/accounts/{address}/events/0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>/withdraw_events` +Query events by handle +URL: `https://{rest_api_server}/accounts/{address}/events/0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>/withdraw_events` ```json [ { @@ -565,24 +461,24 @@ the account resources URL: ] ``` - Gather more information from the transaction that generated the event by - querying `https://{rest_server_api}/transactions/by_version/{version}` - where `{version}` is the same value as the `{version}` in the event query. - - - When tracking full movement of coins, normally events are - sufficient. `0x1::aptos_coin::AptosCoin`, however, requires - considering `gas_used` for each transaction sent from the given account - since it represents gas in Aptos. To reduce unnecessary overhead, extracting - gas fees due to transactions does not emit an event. All transactions for an - account can be retrieved from this API: - `https://{rest_server_api}/accounts/{address}/transactions` - +Gather more information from the transaction that generated the event by +querying `https://{rest_server_api}/transactions/by_version/{version}` +where `{version}` is the same value as the `{version}` in the event query. + + + When tracking full movement of coins, normally events are + sufficient. `0x1::aptos_coin::AptosCoin`, however, requires + considering `gas_used` for each transaction sent from the given account + since it represents gas in Aptos. To reduce unnecessary overhead, extracting + gas fees due to transactions does not emit an event. All transactions for an + account can be retrieved from this API: + `https://{rest_server_api}/accounts/{address}/transactions` + - ### Tracking coin balance changes +### Tracking coin balance changes - Consider the transaction from the earlier section, but now with an arbitrary - coin `0x1337::my_coin::MyCoin` and some gas parameters changed: +Consider the transaction from the earlier section, but now with an arbitrary +coin `0x1337::my_coin::MyCoin` and some gas parameters changed: ```json { @@ -604,7 +500,7 @@ the account resources URL: "guid": { "id": { "addr": "0x5098df8e7969b58ab3bd2d440c6203f64c60a1fd5c08b9d4abe6ae4216246c3e", - "creation_num": "2", + "creation_num": "2" } } }, @@ -666,133 +562,66 @@ the account resources URL: } ``` - There are three balance changes in this transaction: +There are three balance changes in this transaction: 1. A withdrawal of `1000` of `0x1337::my_coin::MyCoin` from the transaction - sending account `0x810026ca8291dd88b5b30a1d3ca2edd683d33d06c4a7f7c451d96f6d47bc5e8b` +sending account `0x810026ca8291dd88b5b30a1d3ca2edd683d33d06c4a7f7c451d96f6d47bc5e8b` 2. A deposit of `1000` of `0x1337::my_coin::MyCoin` to receiving account `0x5098df8e7969b58ab3bd2d440c6203f64c60a1fd5c08b9d4abe6ae4216246c3e` 3. A gas fee `2200` of `0x1::aptos_coin::AptosCoin` from the sending account `0x810026ca8291dd88b5b30a1d3ca2edd683d33d06c4a7f7c451d96f6d47bc5e8b` - To retrieve the withdrawal information: +To retrieve the withdrawal information: 1. Scan the `changes` for `0x1::coin::CoinStore`. Note the - `CoinType` - is a generic signifying which coin is stored in the store. In this example, - the `CoinType` is `0x1337::my_coin::MyCoin`. +`CoinType` +is a generic signifying which coin is stored in the store. In this example, +the `CoinType` is `0x1337::my_coin::MyCoin`. 2. Retrieve the `guid` for `withdraw_events`. In this example, the `guid` - contains `addr` - `0x810026ca8291dd88b5b30a1d3ca2edd683d33d06c4a7f7c451d96f6d47bc5e8b` - and `creation_num` `3`. +contains `addr` +`0x810026ca8291dd88b5b30a1d3ca2edd683d33d06c4a7f7c451d96f6d47bc5e8b` +and `creation_num` `3`. 3. Scan for events with this `guid` and extract the event associated with it. - In - this example, it is the `0x1::coin::WithdrawEvent`. +In +this example, it is the `0x1::coin::WithdrawEvent`. 4. Note the `amount` field will be the number of `CoinType` removed from the - account in the `guid`. In this example, it is `1000`. +account in the `guid`. In this example, it is `1000`. - To retrieve the deposit information, it's the same as withdrawal except: +To retrieve the deposit information, it's the same as withdrawal except: 1. The `guid` used is under `deposit_events` 2. The `amount` will be a positive increase on the account's balance. 3. The event's name will be: `0x1::coin::DepositEvent` - To retrieve the gas fee: +To retrieve the gas fee: 1. The `gas_used` field must be multiplied times the `gas_unit_price`. In this - example, `gas_used=20` and `gas_unit_price=110` so the total gas coins - withdrawn is `2200`. +example, `gas_used=20` and `gas_unit_price=110` so the total gas coins +withdrawn is `2200`. 2. Gas is always: `0x1::aptos_coin::AptosCoin` - To retrieve information about the number of decimals of the coin: +To retrieve information about the number of decimals of the coin: 1. You can retrieve the number of decimals for a coin via - its: `0x1::coin::CoinInfo` +its: `0x1::coin::CoinInfo` 2. This will be located at the address of the coin type. In this example, you - would need to look up `0x1::coin::CoinInfo<0x1337::my_coin::MyCoin>` at address `0x1337`. - - - If you always use the events in this manner, you won't miss any balance - changes - for an account. - By monitoring the events, you will find all balance changes in - the `0x1::coin::CoinStore`: - - 1. Coin mints - 2. Coin burns - 3. Coin transfers - 4. Staking coins - 5. Withdrawing staked coins - 6. Transfers not derived from `coin::transfer` - - - - To create some sample data to explore, - conduct ["Your first transaction"](../guides/first-transaction.mdx). -To learn more about coin creation, -make ["Your First Coin"](../guides/first-coin.mdx). - -## Integrating with the faucet - -This tutorial is for SDK and wallet developers who want to integrate with -the [Aptos -Faucet](https://github.com/aptos-labs/aptos-core/tree/main/crates/aptos-faucet). -If you are a dapp developer, you should access the faucet through an -existing [SDK](../guides/first-transaction.mdx) -or the [CLI](../cli.mdx) instead. - -### Differences between devnet and testnet - -What are the differences between devnet and testnet? Effectively none. In the -past, the testnet faucet had a Captcha in front of it, making it unqueryable -by -normal means. This is no longer true. - -The endpoints for each faucet are: - -- Devnet: https://faucet.devnet.aptoslabs.com -- Testnet: https://faucet.testnet.aptoslabs.com - -### Calling the faucet: JavaScript / TypeScript +would need to look up `0x1::coin::CoinInfo<0x1337::my_coin::MyCoin>` at address `0x1337`. + + + If you always use the events in this manner, you won't miss any balance + changes + for an account. + By monitoring the events, you will find all balance changes in + the `0x1::coin::CoinStore`: + + 1. Coin mints + 2. Coin burns + 3. Coin transfers + 4. Staking coins + 5. Withdrawing staked coins + 6. Transfers not derived from `coin::transfer` -If you are building a client in JavaScript or TypeScript, you should make use -of the [@aptos-labs/aptos-faucet-client](https://www.npmjs.com/package/@aptos-labs/aptos-faucet-client) -package. This client is generated based on the OpenAPI spec published by the -faucet service. - -Example use: - -```ts filename="index.ts" -import { - AptosFaucetClient, - FundRequest, -} from "@aptos-labs/aptos-faucet-client"; - -async function callFaucet(amount: number, address: string): Promise { - const faucetClient = new AptosFaucetClient({ - BASE: "https://faucet.devnet.aptoslabs.com", - }); - const request: FundRequest = { - amount, - address, - }; - const response = await faucetClient.fund({ requestBody: request }); - return response.txn_hashes; -} -``` - -### Calling the faucet: Other languages - -If you are trying to call the faucet in other languages, you have two options: - -1. Generate a client from -the [OpenAPI spec](https://github.com/aptos-labs/aptos-core/blob/main/crates/aptos-faucet/doc/spec.yaml). -2. Call the faucet on your own. - -For the latter, you will want to build a query similar to this: - -```bash filename="Terminal" -curl -X POST -'https://faucet.devnet.aptoslabs.com/mint?amount=10000&address=0xd0f523c9e73e6f3d68c16ae883a9febc616e484c4998a72d8899a1009e5a89d6' -``` + -This means mint 10000 [octas](../../network/glossary.mdx#Octa) to -address `0xd0f523c9e73e6f3d68c16ae883a9febc616e484c4998a72d8899a1009e5a89d6`. +To create some sample data to explore, +conduct ["Your first transaction"](../guides/first-transaction.mdx). +To learn more about coin creation, +make ["Your First Coin"](../guides/first-coin.mdx). diff --git a/apps/nextra/pages/en/network/blockchain/accounts.mdx b/apps/nextra/pages/en/network/blockchain/accounts.mdx index 84aa64652..89534ea1b 100755 --- a/apps/nextra/pages/en/network/blockchain/accounts.mdx +++ b/apps/nextra/pages/en/network/blockchain/accounts.mdx @@ -37,7 +37,7 @@ Bob: 0x19aadeca9388e009d136245b9a67423f3eee242b03142849eb4f81a4a409e59c ## Account address -Currently, Aptos supports only a single, unified identifier for an account. Accounts on Aptos are universally represented as a 32-byte hex string. A hex string shorter than 32-bytes is also valid; in those scenarios, the hex string can be padded with leading zeroes, e.g., `0x1x` => `0x0000000000000...01`. While Aptos standards indicate leading zeroes may be removed from an Address, most applications attempt to eschew that legacy behavior and only support the removal of 0s for special addresses ranging from `0x0` to `0xa`. +Currently, Aptos supports only a single, unified identifier for an account. Accounts on Aptos are universally represented as a 32-byte hex string. A hex string shorter than 32-bytes is also valid; in those scenarios, the hex string can be padded with leading zeroes, e.g., `0x1` => `0x0000000000000...01`. While Aptos standards indicate leading zeroes may be removed from an Address, most applications attempt to eschew that legacy behavior and only support the removal of 0s for special addresses ranging from `0x0` to `0xa`. ## Creating an account diff --git a/apps/nextra/pages/en/network/blockchain/events.mdx b/apps/nextra/pages/en/network/blockchain/events.mdx index 9c8f602d5..f8c9b5adb 100755 --- a/apps/nextra/pages/en/network/blockchain/events.mdx +++ b/apps/nextra/pages/en/network/blockchain/events.mdx @@ -55,7 +55,7 @@ public fun was_event_emitted(msg: & T): bool ## API Access -There is support for querying both module events and EventHandle events using the [GraphQL API](../../build/guides/system-integrators-guide.mdx#production-network-access). +There is support for querying both module events and EventHandle events using the [GraphQL API](../nodes/networks.mdx). # Event-Handle Events (Deprecated) diff --git a/apps/nextra/pages/en/network/glossary.mdx b/apps/nextra/pages/en/network/glossary.mdx index 8396d5e7a..7b1f780e0 100755 --- a/apps/nextra/pages/en/network/glossary.mdx +++ b/apps/nextra/pages/en/network/glossary.mdx @@ -293,16 +293,7 @@ then there is a guarantee that $T_N$ will never be included in the blockchain. - **Faucet** is a service that mints APT on devnet and testnet. APT on these networks has no real world value, it is only for development purposes. -- You can use the faucet in a few different ways: - - With the [Aptos CLI](../build/cli/trying-things-on-chain/create-test-accounts.mdx). - - Through a wallet, such - as [Petra](https://aptosfoundation.org/ecosystem/project/petra) - or [Pontem](https://aptosfoundation.org/ecosystem/project/pontem-wallet). - See full list - of [Aptos Wallets](https://aptosfoundation.org/ecosystem/projects/wallets). - - Using an SDK, for example by using the `FaucetClient` in the TypeScript SDK. - - With a direct HTTP request. Learn how to do - this [here](../build/guides/system-integrators-guide.mdx#calling-the-faucet-other-languages). +- To use a faucet, see [Faucet API](../build/apis/faucet-api.mdx). ### Fullnodes diff --git a/apps/nextra/pages/en/network/nodes/building-from-source.mdx b/apps/nextra/pages/en/network/nodes/building-from-source.mdx index 1536671ad..9b98abc67 100644 --- a/apps/nextra/pages/en/network/nodes/building-from-source.mdx +++ b/apps/nextra/pages/en/network/nodes/building-from-source.mdx @@ -43,7 +43,7 @@ Windows). Then run the following command to clone the Git repository from GitHub Optionally, check out a release branch to install an Aptos node. We suggest you check out `devnet` for your first development. -See [Choose a network](../../build/guides/system-integrators-guide.mdx) for an +See [Choose a network](networks.mdx) for an explanation of their differences.
diff --git a/apps/nextra/pages/en/network/nodes/localnet/local-development-network.mdx b/apps/nextra/pages/en/network/nodes/localnet/local-development-network.mdx index bcd0c58af..434775a68 100644 --- a/apps/nextra/pages/en/network/nodes/localnet/local-development-network.mdx +++ b/apps/nextra/pages/en/network/nodes/localnet/local-development-network.mdx @@ -120,7 +120,7 @@ As you can see from the example output in step 4, once the local network is runn - [Indexer API](../../../build/indexer/aptos-hosted.mdx): This is a [GraphQL](https://graphql.org/) API that provides rich read access to indexed blockchain data. If you click on the URL for the Indexer API above, by default [http://127.0.0.1:8090](http://127.0.0.1:8090/), it will open the Hasura Console, a web UI that will help you query the Indexer GraphQL API. - [Transaction Stream Service](../../../build/indexer/txn-stream.mdx): This is a gRPC stream of transactions used by the Indexer API. This is only relevant to you if you are developing a [custom processor](../../../build/indexer/custom-processors.mdx). - [Postgres](https://www.postgresql.org/): This is the database that the Indexer processors write to. The Indexer API reads from this database. -- [Faucet](../../../build/guides/system-integrators-guide.mdx#integrating-with-the-faucet): You can use this to fund accounts on your local network. +- [Faucet](../../../build/apis/faucet-api.mdx): You can use this to fund accounts on your local network. If you do not want to run any of these sub-components of a network, there are flags to disable them. diff --git a/apps/nextra/pages/en/network/nodes/networks.mdx b/apps/nextra/pages/en/network/nodes/networks.mdx index f60a68226..e3270eca5 100755 --- a/apps/nextra/pages/en/network/nodes/networks.mdx +++ b/apps/nextra/pages/en/network/nodes/networks.mdx @@ -6,21 +6,30 @@ toc: false # Aptos Networks +## Network Overview + +1. [Localnet](http://127.0.0.1:8080) -- our standalone tool for local development against a known version of the codebase with no external network. +2. [Devnet](https://api.devnet.aptoslabs.com/v1/spec#/) -- a shared resource for the community, data resets weekly, weekly update from aptos-core main branch. +3. [Testnet](https://api.testnet.aptoslabs.com/v1/spec#/) -- a shared resource for the community, data will be preserved, network configuration will mimic Mainnet. +4. [Mainnet](https://api.mainnet.aptoslabs.com/v1/spec#/) -- a production network with real assets. + {/* TODO Make this fit better on the screen */} -| Description | Mainnet | Testnet | Devnet | -| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | -| **Node REST API** | https://api.mainnet.aptoslabs.com/v1 | https://api.testnet.aptoslabs.com/v1 | https://api.devnet.aptoslabs.com/v1 | -| **Node REST API Spec** | Link | Link | Link | -| **Indexer GraphQL API** | https://api.mainnet.aptoslabs.com/v1/graphql | https://api.testnet.aptoslabs.com/v1/graphql | https://api.devnet.aptoslabs.com/v1/graphql | -| **Indexer GraphQL API Spec** | Link | Link | Link | -| **GRPC Transaction Stream** | https://grpc.mainnet.aptoslabs.com | https://grpc.testnet.aptoslabs.com | https://grpc.devnet.aptoslabs.com | -| **Faucet** | No Faucet | https://faucet.testnet.aptoslabs.com/ | https://faucet.devnet.aptoslabs.com/ | -| **Genesis and Waypoint** | https://github.com/aptos-labs/aptos-networks/tree/main/mainnet | https://github.com/aptos-labs/aptos-networks/tree/main/testnet | https://github.com/aptos-labs/aptos-networks/tree/main/devnet | -| **Chain ID** | 1 | 2 | [On Aptos Explorer **select Devnet from top right**](https://explorer.aptoslabs.com/?network=Devnet). | -| **Epoch duration** | 7200 seconds | 7200 seconds | 7200 seconds | -| **Network providers** | Fully decentralized. | Managed by Aptos Labs on behalf of Aptos Foundation. | Managed by Aptos Labs on behalf of Aptos Foundation. | -| **Release cadence** | Monthly | Monthly | Weekly | -| **Wipe cadence** | Never. | Never. | On update. | -| **Purpose** | The main Aptos network. | Long-lived test network. | Bleeding edge and exploratory. | -| **Network status** | Always live. | Always live. | Almost always live, with brief interruptions during updates. | +### Network properties + +| Network Name | Chain ID | Genesis & Waypoint | Epoch Duration | Network Provider | Release Cadence | Wipe Cadence | +|--------------|-------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------|----------------|-----------------------------------------------------|-----------------|--------------| +| Mainnet | 1 | [Files Here](https://github.com/aptos-labs/aptos-networks/tree/main/mainnet) | 2 hours | Fully Decentralized | Monthly, varies | Never | +| Testnet | 2 | [Files Here](https://github.com/aptos-labs/aptos-networks/tree/main/testnet) | 2 hours | Managed by Aptos Labs on behalf of Aptos Foundation | Monthly, varies | Never | +| Devnet | [On Aptos Explorer **select Devnet from top right**](https://explorer.aptoslabs.com/?network=Devnet). | [Files Here](https://github.com/aptos-labs/aptos-networks/tree/main/devnet) | 2 hours | Managed by Aptos Labs on behalf of Aptos Foundation | Weekly | On update | + + +### Network URLs + +The below URLs are provided by Aptos Labs. + +| Network Name | REST API | REST API Spec | Indexer GraphQL API | Indexer GraphQL API Spec | Indexer GRPC | Faucet | +|--------------|--------------------------------------------------|--------------------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|--------------------------------------------|-------------------------------------------------| +| Mainnet | [REST API](https://api.mainnet.aptoslabs.com/v1) | [REST API Spec](https://api.mainnet.aptoslabs.com/v1/spec#/) | [Indexer API](https://api.mainnet.aptoslabs.com/v1/graphql) | [Indexer API Spec](https://cloud.hasura.io/public/graphiql?endpoint=https://api.mainnet.aptoslabs.com/v1/graphql) | [GRPC](https://grpc.mainnet.aptoslabs.com) | N/A | +| Testnet | [REST API](https://api.testnet.aptoslabs.com/v1) | [REST API Spec](https://api.testnet.aptoslabs.com/v1/spec#/) | [Indexer API](https://api.testnet.aptoslabs.com/v1/graphql) | [Indexer API Spec](https://cloud.hasura.io/public/graphiql?endpoint=https://api.testnet.aptoslabs.com/v1/graphql) | [GRPC](https://grpc.testnet.aptoslabs.com) | [Faucet](https://faucet.testnet.aptoslabs.com/) | +| Devnet | [REST API](https://api.devnet.aptoslabs.com/v1) | [REST API Spec](https://api.devnet.aptoslabs.com/v1/spec#/) | [Indexer API](https://api.devnet.aptoslabs.com/v1/graphql) | [Indexer API Spec](https://cloud.hasura.io/public/graphiql?endpoint=https://api.devnet.aptoslabs.com/v1/graphql) | [GRPC](https://grpc.devnet.aptoslabs.com) | [Faucet](https://faucet.devnet.aptoslabs.com/) | diff --git a/apps/nextra/pages/zh/build/apis.mdx b/apps/nextra/pages/zh/build/apis.mdx index 7a891fa3e..c6db63923 100644 --- a/apps/nextra/pages/zh/build/apis.mdx +++ b/apps/nextra/pages/zh/build/apis.mdx @@ -51,7 +51,7 @@ Aptos 区块链网络可以通过多种 API 进行访问,具体取决于您的 ## Faucet (Only Testnet/Devnet) - + Faucet API 该 API 提供在开发网和测试网上接收测试代币的能力。其主要目的是在将应用程序和 Move 合约部署到主网之前进行开发和测试。 diff --git a/apps/nextra/pages/zh/build/apis/faucet-api.mdx b/apps/nextra/pages/zh/build/apis/faucet-api.mdx index 8917f852e..a6ae62afd 100644 --- a/apps/nextra/pages/zh/build/apis/faucet-api.mdx +++ b/apps/nextra/pages/zh/build/apis/faucet-api.mdx @@ -15,10 +15,6 @@ Devnet 和 Testnet 之间有什么区别?实际上没有。过去,Testnet - Devnet: https://faucet.devnet.aptoslabs.com - Testnet: https://faucet.testnet.aptoslabs.com -## 与水龙头集成 - -有关如何在项目中使用水龙头的更多信息,请参阅[系统集成指南](../guides/system-integrators-guide.mdx)。 - ### 通过终端调用水龙头 如果您想在其他语言中调用水龙头,有两种选择: @@ -37,7 +33,7 @@ curl -X POST ### 调用水龙头:JavaScript / TypeScript -如果您正在使用 JavaScript 或 TypeScript 构建客户端,您应该使用 +如果您正在使用 JavaScript 或 TypeScript 构建客户端,您应该使用 [@aptos-labs/aptos-faucet-client](https://www.npmjs.com/package/@aptos-labs/aptos-faucet-client) 包。该客户端是根据水龙头服务发布的 OpenAPI 规范生成的。 diff --git a/apps/nextra/pages/zh/build/apis/fullnode-rest-api.mdx b/apps/nextra/pages/zh/build/apis/fullnode-rest-api.mdx index d0b5c343d..87cc41880 100644 --- a/apps/nextra/pages/zh/build/apis/fullnode-rest-api.mdx +++ b/apps/nextra/pages/zh/build/apis/fullnode-rest-api.mdx @@ -10,10 +10,6 @@ import { Card, Cards } from '@components/index' 该API嵌入到全节点中,提供了一种简单、低延迟、但低级别的方式来读取状态和提交交易到Aptos区块链。它还支持交易模拟。 对于更高级的查询,我们建议使用 [Indexer GraphQL API](../indexer.mdx)。 - -还请参阅[系统集成指南](../guides/system-integrators-guide.mdx),以获得Aptos集成的详细步骤。 - - ## Aptos全节点REST API浏览器 @@ -75,7 +71,7 @@ REST API提供以下方式查询交易和事件: - 相关的 [Move](https://github.com/aptos-labs/aptos-core/blob/90c33dc7a18662839cd50f3b70baece0e2dbfc71/aptos-move/framework/aptos-framework/sources/coin.move#L226) 代码 - [规范](https://github.com/aptos-labs/aptos-core/blob/90c33dc7a18662839cd50f3b70baece0e2dbfc71/api/doc/spec.yaml#L8513)。 -View 函数的操作方式类似于[Aptos 模拟 API](../guides/system-integrators-guide.mdx),但没有副作用,并且具有可访问的输出路径。可以通过 `/view` 端点调用 View 函数。对 View 函数的调用需要模块和函数名称以及输入类型参数和值。 +View 函数的操作方式类似于 Aptos 模拟 API,但没有副作用,并且具有可访问的输出路径。可以通过 `/view` 端点调用 View 函数。对 View 函数的调用需要模块和函数名称以及输入类型参数和值。 函数不必是不可变的才能被标记为 `#[view]`,但如果函数是可变的,则在通过API调用时不会导致状态变更。如果要将可变函数标记为 `#[view]`,可以考虑将其设置为私有函数,以防止在运行时恶意调用。 diff --git a/apps/nextra/pages/zh/build/cli/running-a-local-network.mdx b/apps/nextra/pages/zh/build/cli/running-a-local-network.mdx index 99d918107..cc36c14e4 100644 --- a/apps/nextra/pages/zh/build/cli/running-a-local-network.mdx +++ b/apps/nextra/pages/zh/build/cli/running-a-local-network.mdx @@ -127,7 +127,7 @@ Unexpected error: Failed to apply pre-run steps for Postgres: Docker is not avai - [Indexer API](../indexer/aptos-hosted.mdx):这是一个 [GraphQL](https://graphql.org/) API,它提供了丰富的操作,以允许您读取索引了的区块链数据。点击上述的 Indexer API URL,默认是 [http://127.0.0.1:8090](http://127.0.0.1:8090/),即可打开 Hasura 控制台。这是一个 Web 界面,便于您查询 Indexer GraphQL API。 - [交易流服务](../indexer/txn-stream.mdx):这是一个通过 Indexer API 实现的 gRPC 交易流。仅当您在开发[自定义处理器](../../indexer/custom-processors.mdx)时,此信息对您才有相关性。 - [Postgres](https://www.postgresql.org/):这是 Indexer 处理器用来存储数据的数据库,而 Indexer API 则从此数据库中读取信息。 -- [水龙头(Faucet)](../advanced-guides/system-integrators-guide.mdx#integrating-with-the-faucet):您可以使用它为您的本地网络中的账户提供资金。 +- [水龙头(Faucet)](../../../build/apis/faucet-api.mdx):您可以使用它为您的本地网络中的账户提供资金。 如果您不想运行网络的任何这些子组件,可以使用一些参数来禁用它们。 diff --git a/apps/nextra/pages/zh/network/nodes/building-from-source.mdx b/apps/nextra/pages/zh/network/nodes/building-from-source.mdx index a00c6a891..e2e2e089b 100644 --- a/apps/nextra/pages/zh/network/nodes/building-from-source.mdx +++ b/apps/nextra/pages/zh/network/nodes/building-from-source.mdx @@ -36,7 +36,7 @@ Aptos 可以在包括 Linux、macOS 和 Windows 在内的各种操作系统上 这是可选的:切换到 `release` 分支以安装 Aptos 节点。 我们建议你首先切换到 `devnet` 进行开发。 -查看[选择网络](../../build/advanced-guides/system-integrators-guide.mdx)了解它们之间的区别。 +查看[选择网络](networks.mdx)了解它们之间的区别。
发布分支