diff --git a/docs/contrib/README.md b/docs/contrib/README.md index 527a20cbf6..52b5ad42ae 100644 --- a/docs/contrib/README.md +++ b/docs/contrib/README.md @@ -8,9 +8,6 @@ low-level access to it's endpoints, when necessary. It uses the following Javascript technologies and principles: -- [stampit] provides composable Factories based on the [Stamp - Specification]. This is how aepp-sdk approached the [composition over - inheritance] principle. - [JavaScript the Good Parts] (because Crockford is always right) - [ES6 modules], using `export` and `import` - [Promises] using ES7 [async/await] syntax, where applicable @@ -65,11 +62,11 @@ npm run docs:examples && npm run docs:api ## Building -aepp-sdk is built using [pnpm]. In order to build a development version, launch the `build:dev` command. +aepp-sdk is built using npm. In order to build a development version, launch the `build:dev` command. ```bash -pnpm install -pnpm run build:dev +npm install +npm run build:dev ``` ## Testing @@ -77,7 +74,7 @@ pnpm run build:dev To test, launch the `test` command. This will run [mocha](https://mochajs.org/)'s tests locally. ```bash -pnpm run test +npm test ``` This repository also includes a docker-compose file, to allow you to **run your own æternity node locally**. If you want to do so, **from the root of the project**: @@ -96,34 +93,11 @@ services: 2. Run `docker-compose up node` 3. Congrats! you're now running your own æternity node locally. - -## Composing new Flavors -You can also "compose" your own flavor by mixing 2 or more flavors likes so: - -```js -import { Wallet, Contract, MemoryAccount } from '@aeternity/aepp-sdk' - -// make a "mixed flavor" containing Wallet and Contracts flavors -Wallet.compose(Contract)({ - url: 'https://testnet.aeternity.io', - accounts: [new MemoryAccount({keypair: {secretKey: account.priv, publicKey: account.pub}})], - address: account.pub, - onTx: true, // or a function to Guard the Rpc client - onChain: true, // or a function to Guard the Rpc client - onAccount: true, // or a function to Guard the Rpc client - networkId: 'ae_uat' - }).then(ae => { - // ae is your initialised client now! :) - // ... -``` - The WebPack compilation provides two different build artifacts in `dist/`, one for Node.js and one for browsers. When referencing aepp-sdk through any modern build tooling, it should pick the right one automatically through the entry points defined in `package.json`. -[pnpm]: https://pnpm.js.org/ - ## Installation / Linking In order to add a local development version of aepp-sdk to a project, `npm link`[1] can be used. diff --git a/docs/guides/aens.md b/docs/guides/aens.md index 66c6967c72..c2be179642 100644 --- a/docs/guides/aens.md +++ b/docs/guides/aens.md @@ -18,7 +18,7 @@ Claiming an AENS name requires you (at least) 2 transactions: ```js // imports -const aeSdk = await Universal({ ... }) // init the SDK instance with Universal Stamp +const aeSdk = new AeSdk({ ... }) // init the SDK instance with AeSdk class const name = 'testNameForTheGuide.chain' @@ -188,7 +188,7 @@ const pointers = { channel: 'ch_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk', } -// using aeSdk directly (instance of Universal Stamp) +// using aeSdk directly (instance of AeSdk class) const nameUpdateTx = await aeSdk.aensUpdate(name, pointers) // OR using the instance of a name @@ -244,7 +244,7 @@ In case you want to extend a name using a custom TTL and keep the current pointe ```js const name = 'testNameForTheGuide.chain' -// using aeSdk directly (instance of Universal Stamp) +// using aeSdk directly (instance of AeSdk class const nameUpdateTx = await aeSdk.aensUpdate(name, {}, { nameTtl: 100000, extendPointers: true }) // OR using the instance of a name @@ -289,7 +289,7 @@ In some cases you might want to transfer the ownership of a name to another acco ```js const recipient = 'ak_...' -// using aeSdk directly (instance of Universal Stamp) +// using aeSdk directly (instance of AeSdk class) const nameTransferTx = await aeSdk.aensTransfer(name, recipient) // OR using the instance of a name @@ -323,7 +323,7 @@ console.log(nameTransferTx) ## 4. Revoke a name In case you want to revoke a name prior to its expiration for whatever reason you can do that as follows: ```js -// using aeSdk directly (instance of Universal Stamp) +// using aeSdk directly (instance of AeSdk class) const nameRevokeTx = await aeSdk.aensRevoke(name) // OR using the instance of a name @@ -366,7 +366,7 @@ This functionality could for example be used to build an AENS marketplace. ```js // imports -const aeSdk = await Universal({ ... }) // init the SDK instance with Universal Stamp +const aeSdk = new AeSdk({ ... }) // init the SDK instance with AeSdk class // contract address const contractId = 'ct_asd2ks...' diff --git a/docs/guides/build-wallet.md b/docs/guides/build-wallet.md index 2597f99be9..6aa3cfabfe 100644 --- a/docs/guides/build-wallet.md +++ b/docs/guides/build-wallet.md @@ -38,8 +38,8 @@ const readyStateCheckInterval = setInterval(function () { }, 10) ``` -### 2. Initialize `RpcWallet` Stamp -Then you need to initialize `RpcWallet` Stamp in your extension and subscribe for new `runtime` connections. +### 2. Initialize `AeSdkWallet` class +Then you need to initialize `AeSdkWallet` class in your extension and subscribe for new `runtime` connections. After the connection is established you can share the wallet details with the application. ```js @@ -54,15 +54,12 @@ const accounts = [ const aeppInfo = {} async function init () { - // Init extension stamp from sdk - RpcWallet({ + const aeSdk = new AeSdkWallet({ compilerUrl: COMPILER_URL, nodes: [{ name: 'testnet', instance: new Node(NODE_URL) }], id: browser.runtime.id, type: WALLET_TYPE.extension, name: 'Wallet WebExtension', - // The `ExtensionProvider` uses the first account by default. You can change active account using `selectAccount(address)` function - accounts, // Hook for sdk registration onConnection (aeppId, params) { if (!confirm(`Aepp ${params.name} with id ${aeppId} wants to connect`)) { @@ -97,18 +94,19 @@ async function init () { throw new RpcRejectedByUserError() } } - }).then(wallet => { - chrome.runtime.onConnect.addListener(async function (port) { - // create connection - const connection = new BrowserRuntimeConnection({ port }) - // add new aepp to wallet - const clientId = aeSdk.addRpcClient(connection) - // share wallet details - aeSdk.shareWalletInfo(clientId) - setInterval(() => aeSdk.shareWalletInfo(clientId), 3000) - }) - }).catch(err => { - console.error(err) + }) + // You can change active account using `selectAccount(address)` function + await aeSdk.addAccount(accounts[0], { select: true }) + await aeSdk.addAccount(accounts[1]) + + chrome.runtime.onConnect.addListener(async function (port) { + // create connection + const connection = new BrowserRuntimeConnection({ port }) + // add new aepp to wallet + const clientId = aeSdk.addRpcClient(connection) + // share wallet details + aeSdk.shareWalletInfo(clientId) + setInterval(() => aeSdk.shareWalletInfo(clientId), 3000) }) } @@ -128,20 +126,18 @@ const accounts = [ ] async function init () { - // Init extension stamp from sdk - RpcWallet({ + // Init extension class from sdk + const aeSdk = new AeSdkWallet({ compilerUrl: COMPILER_URL, nodes: [{ name: 'testnet', instance: new Node(NODE_URL) }], id: browser.runtime.id, type: WALLET_TYPE.extension, name: 'Wallet WebExtension', - // The `ExtensionProvider` uses the first account by default. You can change active account using `selectAccount(address)` function - accounts, // Hook for sdk registration onConnection (aeppId, params, origin) { if (confirm(`Aepp ${params.name} with id ${aeppId} wants to connect`)) { // Whitelist aepp domains for node connection - const aepps = ['https://test', 'https://aepp.aeternity.com'] + const aepps = ['https://aepps.superhero.com', 'https://aepp.aeternity.com'] if (params.connectNode && aepps.includes(origin)) {} else throw new RpcConnectionDenyError() // Connect to aepp without sharing node URLs @@ -177,18 +173,19 @@ async function init () { throw new RpcRejectedByUserError() } } - }).then(wallet => { - chrome.runtime.onConnect.addListener(async function (port) { - // create connection - const connection = new BrowserRuntimeConnection({ port }) - // add new aepp to wallet - const clientId = aeSdk.addRpcClient(connection) - // share wallet details - aeSdk.shareWalletInfo(clientId) - setInterval(() => aeSdk.shareWalletInfo(clientId), 3000) - }) - }).catch(err => { - console.error(err) + }) + // You can change active account using `selectAccount(address)` function + await aeSdk.addAccount(accounts[0], { select: true }) + await aeSdk.addAccount(accounts[1]) + + chrome.runtime.onConnect.addListener(async function (port) { + // create connection + const connection = new BrowserRuntimeConnection({ port }) + // add new aepp to wallet + const clientId = aeSdk.addRpcClient(connection) + // share wallet details + aeSdk.shareWalletInfo(clientId) + setInterval(() => aeSdk.shareWalletInfo(clientId), 3000) }) } diff --git a/docs/guides/connect-aepp-to-wallet.md b/docs/guides/connect-aepp-to-wallet.md index b63a180e8b..bfee417c37 100644 --- a/docs/guides/connect-aepp-to-wallet.md +++ b/docs/guides/connect-aepp-to-wallet.md @@ -10,7 +10,7 @@ You can build your own wallet in the next example ## 1. Specify imports and constants and state ```js -import { RpcAepp, walletDetector, BrowserWindowMessageConnection, Node } from '@aeternity/aepp-sdk' +import { AeSdkAepp, walletDetector, BrowserWindowMessageConnection, Node } from '@aeternity/aepp-sdk' const TESTNET_NODE_URL = 'https://testnet.aeternity.io' const MAINNET_NODE_URL = 'https://mainnet.aeternity.io' @@ -27,11 +27,11 @@ export default { } ``` -## 2. Initialize the `RpcAepp` Stamp +## 2. Initialize the `AeSdkAepp` class ```js -async created () { - this.aeSdk = await RpcAepp({ +created () { + this.aeSdk = new AeSdkAepp({ name: 'Simple Aepp', nodes: [ { name: 'ae_uat', instance: new Node(TESTNET_NODE_URL) }, @@ -73,7 +73,7 @@ methods: { } ``` -## 4. Connect to a wallet +## 4a. Connect to a wallet Append method for wallet connection @@ -87,7 +87,7 @@ async connect(wallet) { } ``` -## 4. Use Wallet's Node for chain communication +## 4b. Connect to a wallet: Use Wallet's Node for chain communication Aepp can request the wallet to share its connected node URLs if any to interact with the chain. diff --git a/docs/guides/contract-events.md b/docs/guides/contract-events.md index 9baf69bf8b..c6b9e30719 100644 --- a/docs/guides/contract-events.md +++ b/docs/guides/contract-events.md @@ -59,7 +59,7 @@ Note: Of course it is also possible to decode the event log if you request the transaction details from the node for a transaction that has been mined already. You can request the transaction details by providing the tx-hash and then decode the event log using the `contractInstance` as follows: ```js const txHash = 'th_2YV3AmAz2kXdTnQxXtR2uxQi3KuLS9wfvXyqKkQQ2Y6dE6RnET'; -// aeSdk is an instance of the Universal Stamp +// aeSdk is an instance of the AeSdk class const txInfo = await aeSdk.api.getTransactionInfoByHash(txHash) // decode events using contract instance diff --git a/docs/guides/contracts.md b/docs/guides/contracts.md index ce798c731a..caee7be3ce 100644 --- a/docs/guides/contracts.md +++ b/docs/guides/contracts.md @@ -17,9 +17,9 @@ Note: ## 1. Specify imports ```js // node.js import -const { Universal, MemoryAccount, Node } = require('@aeternity/aepp-sdk') +const { AeSdk, MemoryAccount, Node } = require('@aeternity/aepp-sdk') // ES import -import { Universal, MemoryAccount, Node } from '@aeternity/aepp-sdk' +import { AeSdk, MemoryAccount, Node } from '@aeternity/aepp-sdk' ``` ## 2. Create an instance of the SDK @@ -32,14 +32,13 @@ const account = new MemoryAccount({ keypair: { secretKey: SECRET_KEY, publicKey: PUBLIC_KEY } }) -const aeSdk = await Universal({ +const aeSdk = new AeSdk({ nodes: [ { name: 'testnet', instance: node } ], compilerUrl: 'https://compiler.aepps.com', // ideally host your own compiler - accounts: [account] }) - +await aeSdk.addAccount(accoount, { select: true }) ``` Note: diff --git a/docs/guides/error-handling.md b/docs/guides/error-handling.md index fd6c686efd..c9d276a54d 100644 --- a/docs/guides/error-handling.md +++ b/docs/guides/error-handling.md @@ -113,7 +113,7 @@ BaseError ```js // import required error classes const { - Universal, + AeSdk, Node, MemoryAccount, generateKeyPair, @@ -129,10 +129,11 @@ const NEW_USER_KEYPAIR = generateKeyPair() const payerAccount = new MemoryAccount({ keypair: PAYER_ACCOUNT_KEYPAIR }) const newUserAccount = new MemoryAccount({ keypair: NEW_USER_KEYPAIR }) const node = new Node(NODE_URL) -const aeSdk = await Universal({ +const aeSdk = new AeSdk({ nodes: [{ name: 'testnet', instance: node }], - accounts: [payerAccount, newUserAccount] }) +await aeSdk.addAccount(payerAccount, { select: true }) +await aeSdk.addAccount(newUserAccount) // catch exceptions try { diff --git a/docs/guides/low-vs-high-usage.md b/docs/guides/low-vs-high-usage.md index 9e22436f2f..93dce285b6 100644 --- a/docs/guides/low-vs-high-usage.md +++ b/docs/guides/low-vs-high-usage.md @@ -6,7 +6,7 @@ *Alexander Kahl.* The purist uses the functions generated out of the Swagger -file. After creating the SDK instance `aeSdk` with the Universal Stamp it exposes a mapping of all `operationId`s as functions, converted to camelCase (from PascalCase). So e.g. in order to get a transaction +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 @@ -18,16 +18,19 @@ of chain operations, so the SDK provides abstractions for these. Example spend function, using æternity's SDK abstraction. ```js -import { MemoryAccount, Node, Universal } from '@aeternity/aepp-sdk' +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 = await Universal({ + const aeSdk = new AeSdk({ nodes: [{ name: 'testnet', instance: node }], compilerUrl: 'https://compiler.aepps.com', // ideally host your own compiler! - accounts: [new MemoryAccount({keypair: {secretKey: '', publicKey: ''}})], }) + await aeSdk.addAccount( + new MemoryAccount({keypair: {secretKey: '', publicKey: ''}}), + { select: true } + ) // log transaction info console.log(await aeSdk.spend(100, 'ak_...')) @@ -37,15 +40,18 @@ async function init () { ## Low-level SDK usage (use [API](https://aeternity.com/protocol/node/api) endpoints directly) Example spend function, using the SDK, talking directly to the [**API**](https://aeternity.com/protocol/node/api): ```js -import { MemoryAccount, Node, Universal } from '@aeternity/aepp-sdk' +import { MemoryAccount, Node, AeSdk } from '@aeternity/aepp-sdk' async function spend (amount, recipient) { const node = new Node('https://testnet.aeternity.io') // ideally host your own node! - const aeSdk = await Universal({ + const aeSdk = new AeSdk({ nodes: [{ name: 'testnet', instance: node }], compilerUrl: 'https://compiler.aepps.com', // ideally host your own compiler! - accounts: [new MemoryAccount({keypair: {secretKey: '', publicKey: ''}})], }) + await aeSdk.addAccount( + new MemoryAccount({keypair: {secretKey: '', publicKey: ''}}), + { select: true } + ) // builds an unsigned SpendTx using the debug endpoint of the node's API const spendTx = await aeSdk.buildTx(TX_TYPE.spend, { diff --git a/docs/guides/oracles.md b/docs/guides/oracles.md index 0166b5207b..460d97e136 100644 --- a/docs/guides/oracles.md +++ b/docs/guides/oracles.md @@ -10,8 +10,8 @@ You register an oracle that responds with the temperature of the city that is in To register an oracle you need to provide a `queryFormat` and a `responseFormat` to the `registerOracle` function of the SDK. In addition to the common transaction options you can provide the oracle specific options `queryFee` and `oracleTtl`, see [transaction options](../transaction-options.md#oracleregistertx). ```js -// init an instance of the SDK using the Universal Stamp -const aeSdk = await Universal({ ... }) +// init an instance of the SDK using the AeSdk class +const aeSdk = new AeSdk({ ... }) // set TTL with a delta of 1000 blocks const oracleTtl = {type: 'delta', value: 1000} @@ -51,7 +51,7 @@ const options = {queryFee: 1337, queryTtl: {type: 'delta', value: 20}, responseT const oracle = await aeSdk.getOracleObject(oracleId) // in case you need to instantiate the oracle object first const query = await oracle.postQuery("{'city': 'Berlin'}", options) // using the oracle instance -// OR using the aeSdk (instance of Universal stamp) directly by providing the oracleId +// OR using the aeSdk (instance of AeSdk class) directly by providing the oracleId const query = await aeSdk.postQueryToOracle(oracleId, "{'city': 'Berlin'}", options) ``` @@ -70,7 +70,7 @@ const queryId = 'oq_...'; const query = await aeSdk.getQueryObject(oracleId, queryId) // in case you need to get the query instance first const response = await query.pollForResponse({ attempts: 10, interval: 6000 }) -// OR using the aeSdk (instance of Universal stamp) directly by providing the oracleId +// OR using the aeSdk (instance of AeSdk class) directly by providing the oracleId const response = await aeSdk.pollForQueryResponse(oracleId, queryId, { attempts: 10, interval: 6000 }) // decode the oracle response @@ -109,14 +109,14 @@ const options = { onAccount: 'ak_...' } // only the account of the oracle can re const query = await aeSdk.getQueryObject(oracleId, queryId) await query.respond('{ "temperature": 27.5 }', options) -// OR using the aeSdk (instance of Universal stamp) directly by providing the oracleId and the queryId +// OR using the aeSdk (instance of AeSdk class) directly by providing the oracleId and the queryId await aeSdk.respondToQuery(oracleId, queryId, '{ "temperature": 27.5 }', options) ``` Note: - Of course the oracle itself would either use an API to get the current temperature for a certain city or ideally directly communicate with measuring devices located in that specific city. -- If the Universal Stamp is initialized with the oracle's account there is no need to pass the `onAccount` option as this is done implicitely. +- If the AeSdk class is initialized with the oracle's account there is no need to pass the `onAccount` option as this is done implicitely. ## 4. Oracle: extend As mentioned above an Oracle has a certain TTL that can be specified when registering it. You might want to extend the TTL of the oracle before it expires. You can do that as follows: @@ -131,11 +131,11 @@ const oracleTtl = { type: 'delta', value: 500 } const oracle = await aeSdk.getOracleObject(oracleId) const extendedOracle = await oracle.extendOracle(oracleTtl) -// OR using the aeSdk (instance of Universal stamp) directly by providing the oracleId +// OR using the aeSdk (instance of AeSdk class) directly by providing the oracleId const extendedOracle = await aeSdk.extendOracleTtl(oracleId, oracleTtl) ``` ## Example applications - [ae-oracle-pricefeed](https://github.com/aeternity/ae-oracle-pricefeed) - - NodeJS example that registers an oracle, extends it if required and responds to queries automatically. \ No newline at end of file + - NodeJS example that registers an oracle, extends it if required and responds to queries automatically. diff --git a/docs/guides/paying-for-tx.md b/docs/guides/paying-for-tx.md index 1132c85af6..7081df574f 100644 --- a/docs/guides/paying-for-tx.md +++ b/docs/guides/paying-for-tx.md @@ -24,4 +24,4 @@ Note: - Game developers that want to quickly onboard new users. - Governance aepps that want people to vote on important proposals without having them to pay anything. - Custodians that want to offer an additional services to cover the transaction fees of their clients. -- ... many more! \ No newline at end of file +- ... many more! diff --git a/docs/index.md b/docs/index.md index 795b16617d..a0ebc5f178 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,14 +30,12 @@ Usage: @@ -87,4 +85,4 @@ xcode-select --install ``` ## Command Line Interface (CLI) -If you don't need to include specific functionality into your application and just want to use or play around with features the SDK provides you can make use of the [💻 CLI](https://github.com/aeternity/aepp-cli-js) and follow the instructions mentioned there. \ No newline at end of file +If you don't need to include specific functionality into your application and just want to use or play around with features the SDK provides you can make use of the [💻 CLI](https://github.com/aeternity/aepp-cli-js) and follow the instructions mentioned there. diff --git a/docs/quick-start.md b/docs/quick-start.md index 12cd3c0fef..d76032ea1e 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -2,11 +2,11 @@ In this example we will send 1 _AE_ coin from one account to another ## 1. Specify imports -For the following snippets in the guide you need to specify multiple imports. Most imports like `Universal`, `MemoryAccount` & `Node` are [Stamps](https://stampit.js.org/essentials/what-is-a-stamp) that compose certain functionalities. Others utility functions like `generateKeyPair` also can be imported. +For the following snippets in the guide you need to specify multiple imports. ```js const { - Universal, + AeSdk, MemoryAccount, Node, AE_AMOUNT_FORMATS, @@ -28,7 +28,7 @@ To receive some _AE_ you can use the [Faucet](https://faucet.aepps.com/). Just p ## 4. Interact with the æternity blockchain This example shows: -- how to create an instance of the SDK using the `Universal` [Stamp](https://stampit.js.org/essentials/what-is-a-stamp) +- how to create an instance of the SDK using the `Aesdk` class - how to spend (send) 1 AE from the account the SDK instance was initialized with to some other AE address ```js @@ -41,11 +41,12 @@ const senderAccount = new MemoryAccount({ (async function () { const node = new Node(NODE_URL) - const aeSdk = await Universal({ + const aeSdk = new AeSdk({ compilerUrl: COMPILER_URL, nodes: [{ name: 'testnet', instance: node }], - accounts: [senderAccount] }) + // Add sender account to the aeSdk state + await aeSdk.addAccount(senderAccount, { select: true }) // spend one AE await aeSdk.spend(1, '', { diff --git a/docs/transaction-options.md b/docs/transaction-options.md index 30c27dedaf..35bdf500eb 100644 --- a/docs/transaction-options.md +++ b/docs/transaction-options.md @@ -7,13 +7,13 @@ The `options` object can be optionally passed to the respective function behind const sender = 'ak_...' const recipient = 'ak_...' const options = { onAccount: sender, denomination: 'ae' } // optional options object -// aeSdk is an instance of the Universal Stamp +// aeSdk is an instance of the AeSdk class await aeSdk.spend(1, recipient, options) // amount, recipient and (optional) options ``` Note: -- Without the `options` object the sender would be the first account defined in the accounts array that is used to initialize the Universal Stamp and the recipient would receive `1 aetto` instead of `1 AE`. +- Without the `options` object the sender would be some other account selected in the instance of AeSdk and the recipient would receive `1 aetto` instead of `1 AE`. ## Common options These options are common and can be provided to every tx-type: diff --git a/docs/tutorials/vuejs/helloworld-blockheight.md b/docs/tutorials/vuejs/helloworld-blockheight.md index a1634d4387..f916718a83 100644 --- a/docs/tutorials/vuejs/helloworld-blockheight.md +++ b/docs/tutorials/vuejs/helloworld-blockheight.md @@ -27,7 +27,7 @@ npm install @aeternity/aepp-sdk