diff --git a/.env b/.env deleted file mode 100644 index a310146a26..0000000000 --- a/.env +++ /dev/null @@ -1,2 +0,0 @@ -NODE_TAG=v6.8.0 -COMPILER_TAG=v7.2.0 diff --git a/.eslintrc.js b/.eslintrc.js index 5b9286c39a..1106acb49f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -23,6 +23,7 @@ module.exports = { ], ignorePatterns: [ 'dist', 'es', 'src/apis', 'docs/api', 'test/environment/ledger/browser', 'types-legacy', + 'docs/examples', 'site', ], rules: { 'rulesdir/tsdoc-syntax': 'error', diff --git a/.github/workflows/docs-develop.yml b/.github/workflows/docs-develop.yml index a166be4af6..c44cec002d 100644 --- a/.github/workflows/docs-develop.yml +++ b/.github/workflows/docs-develop.yml @@ -1,23 +1,30 @@ +# TODO: combine with docs-release using if name: Publish develop docs on: push: branches: ['develop'] - + jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 with: - python-version: 3.8 - - uses: actions/cache@v2 + python-version: 3.11 + - uses: actions/cache@v3 with: path: ~/.cache/pip3 key: ${{ runner.os }}-pip-${{ hashFiles('docs/requirements.txt') }} + - uses: actions/cache@v3 + with: + path: | + ~/.npm + ~/.autorest + key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} - run: pip3 install -r docs/requirements.txt - run: git config --global user.email "github-action@users.noreply.github.com" - run: git config --global user.name "GitHub Action" - - run: mike deploy --push develop \ No newline at end of file + - run: mike deploy --push develop diff --git a/.github/workflows/docs-release.yml b/.github/workflows/docs-release.yml index 2ebf1fb129..a89987fc46 100644 --- a/.github/workflows/docs-release.yml +++ b/.github/workflows/docs-release.yml @@ -2,23 +2,29 @@ name: Publish release docs on: release: types: [released] - + jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 with: - python-version: 3.8 - - uses: actions/cache@v2 + python-version: 3.11 + - uses: actions/cache@v3 with: path: ~/.cache/pip3 key: ${{ runner.os }}-pip-${{ hashFiles('docs/requirements.txt') }} + - uses: actions/cache@v3 + with: + path: | + ~/.npm + ~/.autorest + key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} - run: pip3 install -r docs/requirements.txt + - run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV - run: git config --global user.email "github-action@users.noreply.github.com" - run: git config --global user.name "GitHub Action" - - run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV - - run: mike deploy --push --update-aliases $RELEASE_VERSION latest \ No newline at end of file + - run: mike deploy --push --update-aliases $RELEASE_VERSION latest diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7e7101ecff..3ae182a336 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,5 +1,5 @@ name: Test & build -on: [push, pull_request] +on: [pull_request] jobs: main: runs-on: ubuntu-22.04 @@ -7,10 +7,10 @@ jobs: - run: | wget -q https://packages.erlang-solutions.com/erlang/debian/pool/esl-erlang_25.0.4-1~ubuntu~jammy_amd64.deb sudo apt install --allow-downgrades ./esl-erlang_25.0.4-1~ubuntu~jammy_amd64.deb - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 100 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: 18.x - uses: actions/cache@v3 diff --git a/.gitignore b/.gitignore index 18ce8d8795..bf245d2b08 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ site /src/apis/ /src/tx/builder/schema.generated.ts /tooling/autorest/compiler-swagger.yaml +/tooling/autorest/middleware-openapi.yaml /test/environment/ledger/browser /types-legacy /bin diff --git a/README.md b/README.md index 8f61cea933..c08541bebb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # [æternity](https://aeternity.com)'s JavaScript SDK -[![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/aeternity/aepp-sdk-js.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/aeternity/aepp-sdk-js/context:javascript) +[![main action](https://github.com/aeternity/aepp-sdk-js/actions/workflows/main.yml/badge.svg)](https://github.com/aeternity/aepp-sdk-js/actions/workflows/main.yml) +[![codecov](https://codecov.io/gh/aeternity/aepp-sdk-js/branch/develop/graph/badge.svg?token=wON6gOciRP)](https://codecov.io/gh/aeternity/aepp-sdk-js) +[![docs](https://github.com/aeternity/aepp-sdk-js/actions/workflows/docs-develop.yml/badge.svg)](https://github.com/aeternity/aepp-sdk-js/actions/workflows/docs-develop.yml) [![npm](https://img.shields.io/npm/v/@aeternity/aepp-sdk.svg)](https://www.npmjs.com/package/@aeternity/aepp-sdk) [![npm](https://img.shields.io/npm/l/@aeternity/aepp-sdk.svg)](https://www.npmjs.com/package/@aeternity/aepp-sdk) @@ -50,7 +52,7 @@ We keep our [Changelog](docs/CHANGELOG.md) up to date. ## License ISC License (ISC) -Copyright © 2018 æternity developers +Copyright © 2023 æternity developers Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice diff --git a/commitlint.config.js b/commitlint.config.js index c02a6b35e3..1ff9f4adce 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -12,6 +12,8 @@ module.exports = { 'channel', 'compiler', 'contract', + 'middleware', + 'docs', // TODO: remove after releasing 13.1.0 'deps', 'deps-dev', 'node', diff --git a/docker-compose.yml b/docker-compose.yml index b48c5c7925..3bbbc2739f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: node: - image: aeternity/aeternity:${NODE_TAG} + image: aeternity/aeternity:v6.8.1 hostname: node ports: ["3013:3013", "3113:3113", "3014:3014", "3114:3114"] volumes: @@ -9,6 +9,6 @@ services: - ./docker/accounts_test.json:/home/aeternity/node/data/aecore/.genesis/accounts_test.json compiler: - image: aeternity/aesophia_http:${COMPILER_TAG} + image: aeternity/aesophia_http:v7.4.0 hostname: compiler ports: ["3080:3080"] diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 4fbc019989..1bd7d40b52 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,35 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [13.1.0](https://github.com/aeternity/aepp-sdk-js/compare/v13.0.1...v13.1.0) (2023-07-07) + + +### Features + +* **account:** support signing typed data ([e5acdd4](https://github.com/aeternity/aepp-sdk-js/commit/e5acdd44e056cd60638088d74753f912809e63d2)) +* **aens:** add `ensureName` helper to check names ([f1322b1](https://github.com/aeternity/aepp-sdk-js/commit/f1322b13ab99860719ca47dda8e277ece6f7823c)) +* **aens:** support unicode names claim ([f837e90](https://github.com/aeternity/aepp-sdk-js/commit/f837e9081b0ac7eefa942f31e3056b00bd3768eb)) +* **aepp,wallet:** support inner transaction signing ([725782b](https://github.com/aeternity/aepp-sdk-js/commit/725782b8d84ac426d3a192d40de8e1e155e370bc)) +* **aepp,wallet:** support signing typed data ([78ce3b2](https://github.com/aeternity/aepp-sdk-js/commit/78ce3b259377a719dbf7ada7bf3b744e630f0dac)) +* **compiler:** add `generateAci`, `generateAciBySourceCode` ([981bcf2](https://github.com/aeternity/aepp-sdk-js/commit/981bcf252432a3b96aca92ccd682214c124009e2)) +* **middleware:** generate autorest wrapper ([bd08a08](https://github.com/aeternity/aepp-sdk-js/commit/bd08a087509bb47acf49cd015d5d7016b544094e)) +* **middleware:** implement MiddlewareSubscriber ([b51b0a3](https://github.com/aeternity/aepp-sdk-js/commit/b51b0a3ffb7258f3ed1f25395b95811f39ba0cc7)) + + +### Bug Fixes + +* `onAccount` option in AeSdkMethods ([290758b](https://github.com/aeternity/aepp-sdk-js/commit/290758b1884dc36209194bc6bd760c6063f9edd3)) +* **aens:** more accurate name check in `isNameValid` ([b62dcc6](https://github.com/aeternity/aepp-sdk-js/commit/b62dcc655f086cdf28611837e1ed3de2bae09d37)) +* **aepp:** call `onDetected` always with `newWallet` ([80d97fa](https://github.com/aeternity/aepp-sdk-js/commit/80d97fa4b3d2c3fd5fb710c2bdaae10ab521f129)) +* **contract:** use fallback account if `onAccount` not provided ([9033cd7](https://github.com/aeternity/aepp-sdk-js/commit/9033cd799be5974ebf28a49df181eeb63b1fce84)) +* converting proxied options to JSON ([efebbd1](https://github.com/aeternity/aepp-sdk-js/commit/efebbd139ea85c35e28bdcfe907670743f9fc1f4)) +* provide types in exports field of package.json ([dbd19e7](https://github.com/aeternity/aepp-sdk-js/commit/dbd19e70bca2d6dbc5b2392db478bb98936b63f2)) +* reject prefixes other then provided in isAddressValid ([9462add](https://github.com/aeternity/aepp-sdk-js/commit/9462adde8fab9848fca0a6d9a382dbd34f5e2b8f)) +* **tx-builder:** `buildTx` produces the same type as `unpackTx` accepts ([d3d6c88](https://github.com/aeternity/aepp-sdk-js/commit/d3d6c88607abbfb74acf016fba886540938b216d)) +* **tx-builder:** decode tag in entry error message ([db0d96f](https://github.com/aeternity/aepp-sdk-js/commit/db0d96f156f3e8cfe52c6a7d7411c359f6dae35c)) +* **wallet:** emit internal error if something broke while broadcast ([332d1b5](https://github.com/aeternity/aepp-sdk-js/commit/332d1b567f69bf6b7d3567af43fb805556ac015b)) +* **wallet:** throw reason of internal error to handle it in wallet ([276699b](https://github.com/aeternity/aepp-sdk-js/commit/276699ba22539f75591754d2e2c3c503d528fdf4)) + ### [13.0.1](https://github.com/aeternity/aepp-sdk-js/compare/v13.0.0...v13.0.1) (2023-04-24) diff --git a/docs/README.md b/docs/README.md index 2c6bb44994..5302787539 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,7 +13,7 @@ In case you're not using any JS bundling/compilation technique, the SDK can also ```html ``` -...where `VERSION` is the version number of the SDK you want to use (eg. `8.1.0`). +...where `VERSION` is the version number of the SDK you want to use (eg. `13.1.0`). ### Browser ` diff --git a/examples/browser/aepp/src/Connect.vue b/examples/browser/aepp/src/Connect.vue index 9647214d42..5ec9bcbf63 100644 --- a/examples/browser/aepp/src/Connect.vue +++ b/examples/browser/aepp/src/Connect.vue @@ -58,13 +58,12 @@ export default { walletConnected: false, walletConnecting: null, reverseIframe: null, - reverseIframeWalletUrl: 'http://localhost:9000', + reverseIframeWalletUrl: process.env.VUE_APP_WALLET_URL ?? 'http://localhost:9000', walletInfo: null, }), computed: { ...mapState(['aeSdk']), walletName() { - if (!this.aeSdk) return 'SDK is not ready'; if (!this.walletConnected) return 'Wallet is not connected'; return this.walletInfo.name; }, @@ -113,7 +112,6 @@ export default { await this.aeSdk.disconnectWallet(); this.walletConnected = false; if (this.reverseIframe) this.reverseIframe.remove(); - this.$emit('aeSdk', null); }, }, }; diff --git a/examples/browser/aepp/src/Contracts.vue b/examples/browser/aepp/src/Contracts.vue index 892619bb17..27823160b2 100644 --- a/examples/browser/aepp/src/Contracts.vue +++ b/examples/browser/aepp/src/Contracts.vue @@ -80,7 +80,7 @@ diff --git a/examples/browser/aepp/src/TypedData.vue b/examples/browser/aepp/src/TypedData.vue new file mode 100644 index 0000000000..8307293bd6 --- /dev/null +++ b/examples/browser/aepp/src/TypedData.vue @@ -0,0 +1,170 @@ + + Domain + + + Name + + + + + + Version + + + + + + Network id + + + + + + Contract address + + + + + + + Data + + + Type + + + + + + Data + + + + + + Encoded data + + + + Hash + + + + + Sign + + + Sign + + + Signature + + + + + Verify + + + Signature + + + + + + Signer address + + + + + + Verify + + + Is signature correct + + + + + + diff --git a/examples/browser/aepp/src/components/GenerateSpendTx.vue b/examples/browser/aepp/src/components/GenerateSpendTx.vue new file mode 100644 index 0000000000..c9d9496863 --- /dev/null +++ b/examples/browser/aepp/src/components/GenerateSpendTx.vue @@ -0,0 +1,76 @@ + + Generate spend transaction + + + Recipient address + + + + + + Coins amount + + + + Payload + + + + Increment nonce by 1 + + + (only if you want to pay for this transaction yourself) + + + + Generate + + + Spend transaction + + + + + + diff --git a/examples/browser/aepp/src/components/MessageSign.vue b/examples/browser/aepp/src/components/MessageSign.vue new file mode 100644 index 0000000000..4ad1821822 --- /dev/null +++ b/examples/browser/aepp/src/components/MessageSign.vue @@ -0,0 +1,40 @@ + + Sign a message + + + Message to sign + + + + + + Sign message + + + Message sign result + + + + + + diff --git a/examples/browser/aepp/src/components/SpendCoins.vue b/examples/browser/aepp/src/components/SpendCoins.vue new file mode 100644 index 0000000000..e82bb3c723 --- /dev/null +++ b/examples/browser/aepp/src/components/SpendCoins.vue @@ -0,0 +1,53 @@ + + Spend coins + + + Recipient address + + + + + + Coins amount + + + + Payload + + + + Spend + + + Spend result + + + + + + diff --git a/examples/browser/aepp/src/Value.vue b/examples/browser/aepp/src/components/Value.vue similarity index 100% rename from examples/browser/aepp/src/Value.vue rename to examples/browser/aepp/src/components/Value.vue diff --git a/examples/browser/aepp/src/store.js b/examples/browser/aepp/src/store.js index 65130f4b4d..32d20a5184 100644 --- a/examples/browser/aepp/src/store.js +++ b/examples/browser/aepp/src/store.js @@ -4,13 +4,13 @@ import { AeSdkAepp, Node, CompilerHttp } from '@aeternity/aepp-sdk'; const TESTNET_NODE_URL = 'https://testnet.aeternity.io'; const MAINNET_NODE_URL = 'https://mainnet.aeternity.io'; -const COMPILER_URL = 'https://v7.compiler.stg.aepps.com'; +const COMPILER_URL = 'https://v7.compiler.aepps.com'; const store = createStore({ state: { address: undefined, networkId: undefined, - // AeSdkAepp instance can't be in deep reactive https://github.com/aeternity/aepp-sdk-js/blob/develop/docs/README.md#vue-3 + // AeSdkAepp instance can't be in deep reactive https://github.com/aeternity/aepp-sdk-js/blob/develop/docs/README.md#vue3 aeSdk: shallowReactive(new AeSdkAepp({ name: 'Simple æpp', nodes: [ diff --git a/examples/browser/aepp/src/styles.scss b/examples/browser/aepp/src/styles.scss index 77f45e94c3..1ea40925ba 100644 --- a/examples/browser/aepp/src/styles.scss +++ b/examples/browser/aepp/src/styles.scss @@ -30,7 +30,7 @@ h2 { @extend .mt-2, .font-bold, .text-2xl; } -input:not([type=radio]), textarea { +input:not([type=radio]):not([type=checkbox]), textarea { @extend .bg-gray-900, .text-white, .p-2, .w-full; } diff --git a/examples/browser/aepp/vue.config.js b/examples/browser/aepp/vue.config.js index a7e9344d35..383f082ae8 100644 --- a/examples/browser/aepp/vue.config.js +++ b/examples/browser/aepp/vue.config.js @@ -1,6 +1,7 @@ const { defineConfig } = require('@vue/cli-service'); module.exports = defineConfig({ + publicPath: process.env.PUBLIC_PATH ?? '/', devServer: { port: 9001, }, diff --git a/examples/browser/wallet-iframe/src/App.vue b/examples/browser/wallet-iframe/src/App.vue index 8638240c16..b0aad366e0 100644 --- a/examples/browser/wallet-iframe/src/App.vue +++ b/examples/browser/wallet-iframe/src/App.vue @@ -23,7 +23,7 @@ @@ -31,20 +31,19 @@ import { MemoryAccount, generateKeyPair, AeSdkWallet, Node, CompilerHttp, BrowserWindowMessageConnection, METHODS, WALLET_TYPE, - RpcConnectionDenyError, RpcRejectedByUserError, + RpcConnectionDenyError, RpcRejectedByUserError, unpackTx, decodeFateValue, } from '@aeternity/aepp-sdk'; import Value from './Value.vue'; export default { components: { Value }, - data() { - return { - runningInFrame: window.parent !== window, - nodeName: '', - address: '', - balancePromise: null, - }; - }, + data: () => ({ + aeppUrl: process.env.VUE_APP_AEPP_URL ?? 'http://localhost:9001', + runningInFrame: window.parent !== window, + nodeName: '', + address: '', + balancePromise: null, + }), methods: { async shareWalletInfo(clientId, { interval = 5000, attemps = 5 } = {}) { this.aeSdk.shareWalletInfo(clientId); @@ -79,7 +78,7 @@ export default { const genConfirmCallback = (actionName) => (aeppId, parameters, origin) => { if (!confirm([ `Client ${aeppInfo[aeppId].name} with id ${aeppId} at ${origin} want to ${actionName}`, - JSON.stringify(parameters, null, 2), + Value.methods.valueToString(parameters), ].join('\n'))) { throw new RpcRejectedByUserError(); } @@ -88,7 +87,10 @@ export default { class AccountMemoryProtected extends MemoryAccount { async signTransaction(tx, { aeppRpcClientId: id, aeppOrigin, ...options } = {}) { if (id != null) { - genConfirmCallback(`sign transaction ${tx}`)(id, options, aeppOrigin); + const opt = { ...options, unpackedTx: unpackTx(tx) }; + if (opt.onCompiler) opt.onCompiler = ''; + if (opt.onNode) opt.onNode = ''; + genConfirmCallback(`sign transaction ${tx}`)(id, opt, aeppOrigin); } return super.signTransaction(tx, options); } @@ -100,6 +102,14 @@ export default { return super.signMessage(message, options); } + async signTypedData(data, aci, { aeppRpcClientId: id, aeppOrigin, ...options }) { + if (id != null) { + const opt = { ...options, aci, decodedData: decodeFateValue(data, aci) }; + genConfirmCallback(`sign typed data ${data}`)(id, opt, aeppOrigin); + } + return super.signTypedData(data, aci, options); + } + static generate() { // TODO: can inherit parent method after implementing https://github.com/aeternity/aepp-sdk-js/issues/1672 return new AccountMemoryProtected(generateKeyPair().secretKey); @@ -118,7 +128,7 @@ export default { new AccountMemoryProtected('9ebd7beda0c79af72a42ece3821a56eff16359b6df376cf049aee995565f022f840c974b97164776454ba119d84edc4d6058a8dec92b6edc578ab2d30b4c4200'), AccountMemoryProtected.generate(), ], - onCompiler: new CompilerHttp('https://v7.compiler.stg.aepps.com'), + onCompiler: new CompilerHttp('https://v7.compiler.aepps.com'), name: 'Wallet Iframe', onConnection: (aeppId, params, origin) => { if (!confirm(`Client ${params.name} with id ${aeppId} at ${origin} want to connect`)) { diff --git a/examples/browser/wallet-iframe/vue.config.js b/examples/browser/wallet-iframe/vue.config.js index c05654eb6c..7b45f66e5a 100644 --- a/examples/browser/wallet-iframe/vue.config.js +++ b/examples/browser/wallet-iframe/vue.config.js @@ -1,6 +1,7 @@ const { defineConfig } = require('@vue/cli-service'); module.exports = defineConfig({ + publicPath: process.env.PUBLIC_PATH ?? '/', devServer: { port: 9000, }, diff --git a/examples/browser/wallet-web-extension/src/Popup.vue b/examples/browser/wallet-web-extension/src/Popup.vue index c105bf3001..aab4088f1a 100644 --- a/examples/browser/wallet-web-extension/src/Popup.vue +++ b/examples/browser/wallet-web-extension/src/Popup.vue @@ -23,7 +23,6 @@