From 7de17dbf3745cf7fa0ffe07b3f02d2ac8ed7a717 Mon Sep 17 00:00:00 2001 From: Denis Davidyuk Date: Mon, 18 Nov 2024 18:27:29 +0500 Subject: [PATCH] docs(chain): update Low vs High level API --- docs/guides/low-vs-high-usage.md | 140 ++++++++----------------------- 1 file changed, 34 insertions(+), 106 deletions(-) diff --git a/docs/guides/low-vs-high-usage.md b/docs/guides/low-vs-high-usage.md index 91cc4c7c7b..cd1ab3bd63 100644 --- a/docs/guides/low-vs-high-usage.md +++ b/docs/guides/low-vs-high-usage.md @@ -2,109 +2,37 @@ ## Interactions -> "There are two approaches, purist and high-level." - -_Alexander Kahl._ - -The purist uses the functions generated out of the Swagger -file. After creating the SDK instance `aeSdk` with the AeSdk class it exposes a mapping of all `operationId`s as functions, converted to camelCase (from PascalCase). So e.g. in order to get a transaction -based on its hash you would invoke `aeSdk.api.getTransactionByHash('th_...')`. - -In this way the SDK is simply a mapping of the raw API calls into -JavaScript. It's excellent for low-level control, and as a teaching tool to -understand the node's operations. Most real-world requirements involves a series -of chain operations, so the SDK provides abstractions for these. - -## (**Recommended**) High-level SDK usage - -Example spend function, using æternity's SDK abstraction. - -```js -import { MemoryAccount, Node, AeSdk } from '@aeternity/aepp-sdk'; - -async function init() { - const node = new Node('https://testnet.aeternity.io'); // ideally host your own node! - - const aeSdk = new AeSdk({ - nodes: [{ name: 'testnet', instance: node }], - accounts: [new MemoryAccount('')], - }); - - // log transaction info - console.log(await aeSdk.spend(100, 'ak_...')); -} -``` - -## Low-level SDK usage (use [API](https://docs.aeternity.com/protocol/node/api) endpoints directly) - -Example spend function, using the SDK, talking directly to the [**API**](https://docs.aeternity.com/protocol/node/api): - -```js -import { MemoryAccount, Node, AeSdk, Tag } from '@aeternity/aepp-sdk'; - -async function spend(amount, recipient) { - const node = new Node('https://testnet.aeternity.io'); // ideally host your own node! - const aeSdk = new AeSdk({ - nodes: [{ name: 'testnet', instance: node }], - accounts: [new MemoryAccount('')], - }); - - // builds an unsigned SpendTx using integrated transaction builder - const spendTx = await aeSdk.buildTx(Tag.SpendTx, { - senderId: aeSdk.address, - recipientId: recipient, - amount, // aettos - payload: 'using low-level api is funny', - }); - - // sign the encoded transaction - const signedTx = await aeSdk.signTransaction(spendTx); - - // broadcast the signed tx to the node - console.log(await aeSdk.api.postTransaction({ tx: signedTx })); -} -``` - -Following functions are available with the low-level API right now: - -```js -console.log(aeSdk.api); -/* -{ - getTopHeader: [AsyncFunction (anonymous)], - getCurrentKeyBlock: [AsyncFunction (anonymous)], - getCurrentKeyBlockHash: [AsyncFunction (anonymous)], - getCurrentKeyBlockHeight: [AsyncFunction (anonymous)], - getPendingKeyBlock: [AsyncFunction (anonymous)], - getKeyBlockByHash: [AsyncFunction (anonymous)], - getKeyBlockByHeight: [AsyncFunction (anonymous)], - getMicroBlockHeaderByHash: [AsyncFunction (anonymous)], - getMicroBlockTransactionsByHash: [AsyncFunction (anonymous)], - getMicroBlockTransactionByHashAndIndex: [AsyncFunction (anonymous)], - getMicroBlockTransactionsCountByHash: [AsyncFunction (anonymous)], - getCurrentGeneration: [AsyncFunction (anonymous)], - getGenerationByHash: [AsyncFunction (anonymous)], - getGenerationByHeight: [AsyncFunction (anonymous)], - getAccountByPubkey: [AsyncFunction (anonymous)], - getAccountByPubkeyAndHeight: [AsyncFunction (anonymous)], - getAccountByPubkeyAndHash: [AsyncFunction (anonymous)], - getPendingAccountTransactionsByPubkey: [AsyncFunction (anonymous)], - getAccountNextNonce: [AsyncFunction (anonymous)], - protectedDryRunTxs: [AsyncFunction (anonymous)], - getTransactionByHash: [AsyncFunction (anonymous)], - getTransactionInfoByHash: [AsyncFunction (anonymous)], - postTransaction: [AsyncFunction (anonymous)], - getContract: [AsyncFunction (anonymous)], - getContractCode: [AsyncFunction (anonymous)], - getContractPoI: [AsyncFunction (anonymous)], - getOracleByPubkey: [AsyncFunction (anonymous)], - getOracleQueriesByPubkey: [AsyncFunction (anonymous)], - getOracleQueryByPubkeyAndQueryId: [AsyncFunction (anonymous)], - getNameEntryByName: [AsyncFunction (anonymous)], - getChannelByPubkey: [AsyncFunction (anonymous)], - getPeerPubkey: [AsyncFunction (anonymous)], - getStatus: [AsyncFunction (anonymous)], - getChainEnds: [AsyncFunction (anonymous)] -} -*/ -``` +`AeSdk` is a general, high-level interface that wraps multiple low-level interfaces. A general interface is preferred for its simplicity and resilience to breaking changes. + +But there is also low-level interfaces. It's excellent for additional control, and as a teaching tool to understand the underlying operations. Most real-world requirements involves a series of low-level operations, so the SDK provides abstractions for these. + +### Node API + +The aeternity node exposes [a REST API]. This API is described in the [OpenAPI document]. SDK uses this document to generate a TypeScript client. The result client (implemented in [`Node` class]) a basically a mapping of all node endpoints as functions. + +[a REST API]: https://api-docs.aeternity.io/ +[OpenAPI document]: https://mainnet.aeternity.io/api?oas3 +[`Node` class]: https://docs.aeternity.com/aepp-sdk-js/v14.0.0/api/classes/Node.html + +So to get a transaction based on its hash you would invoke `node.getTransactionByHash('th_fWEsg152BNYcrqA9jDh9VVpacYojCUb1yu45zUnqhmQ3dAAC6')`. In this way the SDK is simply a mapping of the raw API calls into JavaScript. + +### Transaction builder + +Any blockchain state change requires signing a transaction. Transaction should be built according to the [protocol]. SDK implements it in [`buildTx`], [`buildTxAsync`], and [`unpackTx`]. [`buildTxAsync`] requires fewer arguments than [`buildTx`], but it expects the node instance provided in arguments. + +[protocol]: https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/serializations.md#accounts-version-1-basic-accounts +[`buildTx`]: https://docs.aeternity.com/aepp-sdk-js/v14.0.0/api/functions/buildTx.html +[`buildTxAsync`]: https://docs.aeternity.com/aepp-sdk-js/v14.0.0/api/functions/buildTxAsync.html +[`unpackTx`]: https://docs.aeternity.com/aepp-sdk-js/v14.0.0/api/functions/unpackTx.html + +## High-level SDK usage (preferable) + +Example spend call, using æternity's SDK abstraction: + +https://github.com/aeternity/aepp-sdk-js/blob/ac4c7186ee186e392b16dcbf1f7dbebe387c2da5/examples/node/high-level-api.js#L1-L18 + +## Low-level SDK usage + +The same spend execution, but using low-level SDK functions: + +https://github.com/aeternity/aepp-sdk-js/blob/ac4c7186ee186e392b16dcbf1f7dbebe387c2da5/examples/node/low-level-api.js#L1-L19