diff --git a/docs/guides/address-length.md b/docs/guides/address-length.md
index 5413b40d69..a2c3f53e5c 100644
--- a/docs/guides/address-length.md
+++ b/docs/guides/address-length.md
@@ -81,5 +81,5 @@ Running the above code you would get output like
Therefore the minimum address length is 41 chars. All these addresses valid, for example
`ak_11111111111111111111111111111111273Yts` [used] to collect AENS name fees.
-[isAddressValid]: https://docs.aeternity.com/aepp-sdk-js/v13.1.0/api/functions/isAddressValid.html
+[isAddressValid]: https://docs.aeternity.com/aepp-sdk-js/v13.2.1/api/functions/isAddressValid.html
[used]: https://mainnet.aeternity.io/v3/accounts/ak_11111111111111111111111111111111273Yts
diff --git a/docs/guides/contracts.md b/docs/guides/contracts.md
index c024b42536..436a349385 100644
--- a/docs/guides/contracts.md
+++ b/docs/guides/contracts.md
@@ -5,24 +5,33 @@ The smart contract language of the æternity blockchain is [Sophia](https://docs
Before interacting with contracts using the SDK you should get familiar with Sophia itself first. Have a look into [aepp-sophia-examples](https://github.com/aeternity/aepp-sophia-examples) and start rapid prototyping using [AEstudio](https://studio.aepps.com).
-The SDK needs to interact with following components in order to enable smart contract interactions on the æternity blockchain:
-
-- [æternity](https://github.com/aeternity/aeternity) (host your own one or use the public testnet node at `https://testnet.aeternity.io`)
-- [aesophia_http](https://github.com/aeternity/aesophia_http) (host your own one or use the public compiler at `https://v7.compiler.aepps.com`)
-
-Note:
-
-- For production deployments you should ***always*** host these services by yourself.
-
## 1. Specify imports
```js
// node.js import
-const { AeSdk, MemoryAccount, Node, CompilerHttp } = require('@aeternity/aepp-sdk')
+const { AeSdk, MemoryAccount, Node } = require('@aeternity/aepp-sdk')
// ES import
-import { AeSdk, MemoryAccount, Node, CompilerHttp } from '@aeternity/aepp-sdk'
+import { AeSdk, MemoryAccount, Node } from '@aeternity/aepp-sdk'
+// additionally you may need to import CompilerCli or CompilerHttp
+```
+
+## 2. Setup compiler
+Compiler primarily used to generate bytecode to deploy a contract.
+Skip this step if you have a contract bytecode or need to interact with an already deployed contract.
+Out-of-the-box SDK supports [aesophia_cli](https://github.com/aeternity/aesophia_cli) and [aesophia_http](https://github.com/aeternity/aesophia_http) implemented in [CompilerCli](https://docs.aeternity.com/aepp-sdk-js/v13.2.1/api/classes/CompilerCli.html) and [CompilerHttp](https://docs.aeternity.com/aepp-sdk-js/v13.2.1/api/classes/CompilerHttp.html) respectively.
+
+CompilerCli is available only in Node.js and requires Erlang installed (`escript` available in `$PATH`), Windows is supported.
+```js
+const compiler = new CompilerCli()
```
-## 2. Create an instance of the SDK
+CompilerHttp requires a hosted compiler service. Preferable to host your own compiler service since [compiler.aepps.com](https://v7.compiler.aepps.com/api) is planned to be decommissioned. An example of how to run it using [docker-compose](https://github.com/aeternity/aepp-sdk-js/blob/cd8dd7f76a6323383349b48400af0d69c2cfd88e/docker-compose.yml#L11-L14).
+```js
+const compiler = new CompilerHttp('https://v7.compiler.aepps.com') // host your own compiler
+```
+
+Both compiler classes implement the [same interface](https://docs.aeternity.com/aepp-sdk-js/v13.2.1/api/classes/CompilerBase.html) that can be used to generate bytecode and ACI without a Contract instance.
+
+## 3. Create an instance of the SDK
When creating an instance of the SDK you need to provide an account which will be used to sign transactions like `ContractCreateTx` and `ContractCallTx` that will be broadcasted to the network.
```js
@@ -32,7 +41,7 @@ const account = new MemoryAccount(SECRET_KEY)
const aeSdk = new AeSdk({
nodes: [{ name: 'testnet', instance: node }],
accounts: [account],
- onCompiler: new CompilerHttp('https://v7.compiler.aepps.com'), // ideally host your own compiler
+ onCompiler: compiler, // remove if step #2 skipped
})
```
@@ -42,7 +51,7 @@ Note:
- For each transaction you can choose a specific account to use for signing (by default the first account will be used), see [transaction options](../transaction-options.md).
- This is specifically important and useful for writing tests.
-## 3. Initialize the contract instance
+## 4. Initialize the contract instance
### By source code
@@ -59,6 +68,13 @@ Note:
const contract = await aeSdk.initializeContract({ sourceCode, fileSystem })
```
+### By path to source code (available only in Node.js)
+It can be used with both CompilerCli and CompilerHttp. This way contract imports would be handled automatically, with no need to provide `fileSystem` option.
+```js
+const sourceCodePath = './example.aes'
+const contract = await aeSdk.initializeContract({ sourceCodePath })
+```
+
### By ACI and bytecode
If you pre-compiled the contracts you can also initialize a contract instance by providing ACI and bytecode:
@@ -80,7 +96,7 @@ const contract = await aeSdk.initializeContract({ aci, address })
### Options
- Following attributes can be provided via `options` to `initializeContract`:
- - `aci` (default: obtained via http compiler)
+ - `aci` (default: obtained via `onCompiler`)
- The Contract ACI.
- `address`
- The address where the contract is located at.
@@ -94,7 +110,11 @@ const contract = await aeSdk.initializeContract({ aci, address })
- You wouldn't want to provide an `amount` to each transaction or use the same `nonce` which would result in invalid transactions.
- For options like `ttl` or `gasPrice` it does absolutely make sense to set this on contract instance level.
-## 4. Deploy the contract
+### Keep bytecode and ACI for future use
+After the contract is initialized you can persist values of `contract._aci` and `contract.$options.bytecode`.
+They can be provided for subsequent contract initializations to don't depend on a compiler.
+
+## 5. Deploy the contract
If you have a Sophia contract source code that looks like this:
```sophia
@@ -131,7 +151,7 @@ Note:
- In Sophia all `public functions` are called `entrypoints` and need to be declared as `stateful`
if they should produce changes to the state of the smart contract, see `increment(value: int)`.
-## 5. Call contract entrypoints
+## 6. Call contract entrypoints
### a) Stateful entrypoints
According to the example above you can call the `stateful` entrypoint `increment` by using one of the following lines:
@@ -187,21 +207,13 @@ const tx = await contract.$call('fund_project', [1], { amount: 50 })
As already stated various times in the guide it is possible to provide [transaction options](../transaction-options.md) as object to a function of the SDK that builds and potentially broadcasts a transaction. This object can be passed as additional param to each of these functions and overrides the default settings.
## Sophia datatype cheatsheet
-Sometimes you might wonder how to pass params to the JavaScript method that calls an entrypoint of your Sophia smart contract. The following table may help you out.
-
-| Type | Sophia entrypoint definition | JavaScript method call |
-|-----------|-----------------------------------|--------------------------------------------------|
-| int | `add_two(one: int, two: int)` | `add_two(1 , 2)` |
-| address | `set_owner(owner: address)` | `set_owner('ak_1337...')` |
-| bool | `is_it_true(answer: bool)` | `is_it_true(true)` |
-| bits | `give_me_bits(input: bits)` | `give_me_bits(0b10110n)` |
-| bytes | `get_bytes(test: bytes(3))` | `get_bytes(new Uint8Array([0x1, 0x1f, 0x10]))` |
-| string | `hello_world(say_hello: string)` | `hello_world('Hello!')` |
-| list | `have_a_few(candy: list(string))` | `have_a_few(['Skittles', 'M&Ms', 'JellyBelly'])` |
-| tuple | `a_few_things(things: (string * int * map(address, bool)))` | `a_few_things(['hola', 3, new Map([['ak_1337...', true]])])` |
-| record | `record user = {`
`firstname: string,`
`lastname: string`
`}`
`get_firstname(input: user): string` | `get_firstname({'firstname': 'Alfred', 'lastname': 'Mustermann'})` |
-| map | `balances(values: map(address, int))` | `balances(new Map([['ak_1337...', 123], ['ak_FCKGW...', 321], ['ak_Rm5U...', 999]]))` |
-| option() | `number_defined(value: option(int)): bool = `
`Option.is_some(value)` | `// the datatype in the option()`
`number_defined(1337) // int in this case` |
-| hash | `a_gram(of: hash)` | `// 32 bytes signature`
`a_gram('af01...490f')` |
-| signature | `one_signature(sig: signature)` | `// 64 bytes signature`
`one_signature('af01...490f')` |
-| functions | (Higher order) functions are not allowed in `entrypoint` params | |
+Sometimes you might wonder how to pass params to the JavaScript method that calls an entrypoint of your Sophia smart contract.
+The conversion between JS and Sophia values is handled by aepp-calldata library.
+Refer to [its documentation](https://www.npmjs.com/package/@aeternity/aepp-calldata#data-types) to find the right type to use.
+
+## Generate file system object in Node.js
+To do so you can use [getFileSystem](https://docs.aeternity.com/aepp-sdk-js/v13.2.1/api/functions/getFileSystem.html) function.
+In most cases, you don't need to do it explicitly. Prefer to use `sourceCodePath` instead `sourceCode` in
+[Contract::initialize](https://docs.aeternity.com/aepp-sdk-js/v13.2.1/api/classes/_internal_.Contract.html#initialize),
+and [compile](https://docs.aeternity.com/aepp-sdk-js/v13.2.1/api/classes/CompilerBase.html#compile)
+instead [compileBySourceCode](https://docs.aeternity.com/aepp-sdk-js/v13.2.1/api/classes/CompilerBase.html#compileBySourceCode) in CompilerBase.
diff --git a/docs/guides/paying-for-tx.md b/docs/guides/paying-for-tx.md
index 98eb8e579f..3621ea814d 100644
--- a/docs/guides/paying-for-tx.md
+++ b/docs/guides/paying-for-tx.md
@@ -13,8 +13,8 @@ You can then collect the signed inner transaction, wrap it into a `PayingForTx`
## Usage examples
We provided following two NodeJS examples which you can take a look at:
-- [InnerTx: ContractCallTx](https://docs.aeternity.com/aepp-sdk-js/v13.1.0/examples/node/paying-for-contract-call-tx/)
-- [InnerTx: SpendTx](https://docs.aeternity.com/aepp-sdk-js/v13.1.0/examples/node/paying-for-spend-tx/)
+- [InnerTx: ContractCallTx](https://docs.aeternity.com/aepp-sdk-js/v13.2.1/examples/node/paying-for-contract-call-tx/)
+- [InnerTx: SpendTx](https://docs.aeternity.com/aepp-sdk-js/v13.2.1/examples/node/paying-for-spend-tx/)
Note:
diff --git a/examples/node/transfer-ae.mjs b/examples/node/transfer-ae.mjs
index 7a90392de4..c4dcb6d230 100755
--- a/examples/node/transfer-ae.mjs
+++ b/examples/node/transfer-ae.mjs
@@ -53,7 +53,7 @@ console.log(`Balance of ${recipient} (before): ${balanceBefore} aettos`);
// Calling the `spend` function will create, sign and broadcast a `SpendTx` to the network.
const tx = await aeSdk.spend(amount, recipient);
console.log('Transaction mined', tx);
-// Alternatively, you can use [transferFunds](https://docs.aeternity.com/aepp-sdk-js/v13.1.0/api/functions/transferFunds.html)
+// Alternatively, you can use [transferFunds](https://docs.aeternity.com/aepp-sdk-js/v13.2.1/api/functions/transferFunds.html)
// method to transfer a fraction of your AE to another account.
// ## 6. Get AE balance of recipient (after transfer)
diff --git a/src/Middleware.ts b/src/Middleware.ts
index fafb521234..e6eea637a8 100644
--- a/src/Middleware.ts
+++ b/src/Middleware.ts
@@ -105,7 +105,7 @@ export default class Middleware
/**
* @param url - Url for middleware API
* @param options - Options
- * @param options.ignoreVersion - Don't check node version
+ * @param options.ignoreVersion - Don't ensure that the middleware is supported
* @param options.retryCount - Amount of extra requests to do in case of failure
* @param options.retryOverallDelay - Time in ms to wait between all retries
*/
diff --git a/src/Node.ts b/src/Node.ts
index ff22ae8f81..a851a191c0 100644
--- a/src/Node.ts
+++ b/src/Node.ts
@@ -116,7 +116,7 @@ export default class Node extends (NodeTransformed as unknown as NodeTransformed
/**
* @param url - Url for node API
* @param options - Options
- * @param options.ignoreVersion - Don't check node version
+ * @param options.ignoreVersion - Don't ensure that the node is supported
* @param options.retryCount - Amount of extra requests to do in case of failure
* @param options.retryOverallDelay - Time in ms to wait between all retries
*/
diff --git a/src/contract/compiler/Cli.ts b/src/contract/compiler/Cli.ts
index 47ee9babc1..149919c4b4 100644
--- a/src/contract/compiler/Cli.ts
+++ b/src/contract/compiler/Cli.ts
@@ -17,14 +17,19 @@ const getPackagePath = (): string => {
};
/**
- * A wrapper around aesophia_cli, available only in Node.js
- * Assumes that `escript` is available in PATH.
+ * A wrapper around aesophia_cli, available only in Node.js.
+ * Requires Erlang installed, assumes that `escript` is available in PATH.
*/
export default class CompilerCli extends CompilerBase {
#path: string;
#ensureCompatibleVersion = Promise.resolve();
+ /**
+ * @param compilerPath - A path to aesophia_cli binary, by default uses the integrated one
+ * @param options - Options
+ * @param options.ignoreVersion - Don't ensure that the compiler is supported
+ */
constructor(
compilerPath = resolve(getPackagePath(), './bin/aesophia_cli'),
{ ignoreVersion }: { ignoreVersion?: boolean } = {},