├── .editorconfig ├── .eslintrc.cjs ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── codeql.yml │ ├── docs.yml │ └── main.yml ├── .gitignore ├── .mocharc.cjs ├── .prettierrc ├── LICENSE ├── README.md ├── babel.config.js ├── babel.esm.config.js ├── commitlint.config.js ├── docker-compose.yml ├── docker ├── aeternity.yaml └── middleware.yaml ├── docs ├── .gitignore ├── CHANGELOG.md ├── README.md ├── build-assets.sh ├── compatibility.md ├── contrib │ ├── README.md │ └── releases.md ├── guides │ ├── address-length.md │ ├── aens.md │ ├── batch-requests.md │ ├── build-wallet.md │ ├── connect-aepp-to-wallet.md │ ├── contract-events.md │ ├── contracts.md │ ├── error-handling.md │ ├── jwt.md │ ├── ledger-wallet.md │ ├── low-vs-high-usage.md │ ├── metamask-snap.md │ ├── migration │ │ ├── 10.md │ │ ├── 11.md │ │ ├── 12.md │ │ ├── 13.md │ │ ├── 14.md │ │ ├── 7.md │ │ └── 9.md │ ├── oracles.md │ ├── paying-for-tx.md │ ├── typed-data.md │ └── typescript.md ├── hooks.py ├── images │ └── favicon.png ├── quick-start.md ├── requirements.txt ├── transaction-options.md └── tutorials │ └── vuejs │ └── helloworld-blockheight.md ├── examples ├── README.md ├── browser │ ├── README.md │ ├── aepp │ │ ├── README.md │ │ ├── babel.config.js │ │ ├── package.json │ │ ├── public │ │ │ ├── icon.svg │ │ │ ├── index.html │ │ │ └── webmanifest.json │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── Basic.vue │ │ │ ├── Connect.vue │ │ │ ├── Contracts.vue │ │ │ ├── DelegationSignature.vue │ │ │ ├── Jwt.vue │ │ │ ├── PayForTx.vue │ │ │ ├── TypedData.vue │ │ │ ├── components │ │ │ │ ├── ConnectFrame.vue │ │ │ │ ├── ConnectLedger.vue │ │ │ │ ├── ConnectMetamask.vue │ │ │ │ ├── ConnectMnemonic.vue │ │ │ │ ├── DataSign.vue │ │ │ │ ├── FieldAction.vue │ │ │ │ ├── GenerateSpendTx.vue │ │ │ │ ├── MessageSign.vue │ │ │ │ ├── SelectNetwork.vue │ │ │ │ ├── SpendCoins.vue │ │ │ │ └── Value.vue │ │ │ ├── main.js │ │ │ ├── store.js │ │ │ └── styles.scss │ │ └── vue.config.js │ ├── tools │ │ ├── index.html │ │ ├── package.json │ │ ├── public │ │ │ └── preact.svg │ │ ├── src │ │ │ ├── app.tsx │ │ │ ├── components │ │ │ │ ├── AccountsByMnemonic.tsx │ │ │ │ ├── ConvertSk.tsx │ │ │ │ ├── DataEncoder.tsx │ │ │ │ └── TransactionPacker.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ └── vite.config.ts │ ├── wallet-iframe │ │ ├── README.md │ │ ├── babel.config.js │ │ ├── package.json │ │ ├── public │ │ │ └── index.html │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── Value.vue │ │ │ ├── main.js │ │ │ └── styles.scss │ │ └── vue.config.js │ └── wallet-web-extension │ │ ├── README.md │ │ ├── babel.config.js │ │ ├── package.json │ │ ├── public │ │ ├── browser-extension.html │ │ └── icons │ │ │ ├── 128.png │ │ │ └── 34.png │ │ ├── src │ │ ├── Popup.vue │ │ ├── background.js │ │ ├── content-script.js │ │ ├── manifest.json │ │ ├── popup.js │ │ └── styles.scss │ │ └── vue.config.js └── node │ ├── _api-high-level.js │ ├── _api-low-level.js │ ├── account-generalized.js │ ├── contract-interaction.js │ ├── dry-run-using-debug-endpoint.js │ ├── oracle.js │ ├── paying-for-contract-call-tx.js │ ├── paying-for-spend-tx.js │ └── transfer-ae.js ├── mkdocs.yml ├── package-lock.json ├── package.json ├── src ├── AeSdk.ts ├── AeSdkAepp.ts ├── AeSdkBase.ts ├── AeSdkMethods.ts ├── AeSdkWallet.ts ├── Middleware.ts ├── MiddlewareSubscriber.ts ├── Node.ts ├── account │ ├── Base.ts │ ├── BaseFactory.ts │ ├── Generalized.ts │ ├── Ledger.ts │ ├── LedgerFactory.ts │ ├── Memory.ts │ ├── Metamask.ts │ ├── MetamaskFactory.ts │ ├── MnemonicFactory.ts │ └── Rpc.ts ├── aens.ts ├── aepp-wallet-communication │ ├── WalletConnectorFrame.ts │ ├── WalletConnectorFrameBase.ts │ ├── WalletConnectorFrameWithNode.ts │ ├── connection-proxy.ts │ ├── connection │ │ ├── Browser.ts │ │ ├── BrowserRuntime.ts │ │ └── BrowserWindowMessage.ts │ ├── rpc │ │ ├── RpcClient.ts │ │ └── types.ts │ ├── schema.ts │ └── wallet-detector.ts ├── chain.ts ├── channel │ ├── Base.ts │ ├── Contract.ts │ ├── Spend.ts │ ├── handlers.ts │ └── internal.ts ├── contract │ ├── Contract.ts │ ├── compiler │ │ ├── Base.ts │ │ ├── Cli.ts │ │ ├── Http.ts │ │ ├── HttpNode.ts │ │ └── getFileSystem.ts │ └── ga.ts ├── index-browser.ts ├── index.ts ├── oracle │ ├── Oracle.ts │ ├── OracleBase.ts │ └── OracleClient.ts ├── send-transaction.ts ├── spend.ts ├── tx │ ├── builder │ │ ├── SchemaTypes.ts │ │ ├── common.ts │ │ ├── constants.ts │ │ ├── delegation │ │ │ ├── index.ts │ │ │ └── schema.ts │ │ ├── entry │ │ │ ├── constants.ts │ │ │ ├── index.ts │ │ │ └── schema.ts │ │ ├── field-types │ │ │ ├── abi-version.ts │ │ │ ├── address.ts │ │ │ ├── array.ts │ │ │ ├── boolean.ts │ │ │ ├── coin-amount.ts │ │ │ ├── ct-version.ts │ │ │ ├── encoded.ts │ │ │ ├── entry.ts │ │ │ ├── enumeration.ts │ │ │ ├── fee.ts │ │ │ ├── field.ts │ │ │ ├── gas-limit.ts │ │ │ ├── gas-price.ts │ │ │ ├── interface.ts │ │ │ ├── map.ts │ │ │ ├── mptree.ts │ │ │ ├── name-fee.ts │ │ │ ├── name-id.ts │ │ │ ├── name.ts │ │ │ ├── nonce.ts │ │ │ ├── pointers.ts │ │ │ ├── query-fee.ts │ │ │ ├── raw.ts │ │ │ ├── short-u-int-const.ts │ │ │ ├── short-u-int.ts │ │ │ ├── string.ts │ │ │ ├── transaction.ts │ │ │ ├── ttl.ts │ │ │ ├── u-int.ts │ │ │ ├── with-default.ts │ │ │ ├── with-formatting.ts │ │ │ └── wrapped.ts │ │ ├── helpers.ts │ │ ├── index.ts │ │ └── schema.ts │ ├── execution-cost.ts │ ├── transaction-signer.ts │ └── validator.ts ├── typings │ ├── blakejs │ │ └── index.d.ts │ ├── sha-js │ │ └── index.d.ts │ └── tweetnacl-auth │ │ └── index.d.ts └── utils │ ├── MiddlewarePage.ts │ ├── amount-formatter.ts │ ├── autorest.ts │ ├── bignumber.ts │ ├── bytes.ts │ ├── crypto.ts │ ├── encoder-types.ts │ ├── encoder.ts │ ├── errors.ts │ ├── json-big.ts │ ├── jwt.ts │ ├── other.ts │ ├── semver-satisfies.ts │ ├── string.ts │ ├── typed-data.ts │ └── wrap-proxy.ts ├── test ├── charts │ ├── dynamic-gas-price.html │ └── node-stats.html ├── emitter │ ├── Dockerfile │ └── main.js ├── environment │ ├── browser-aepp.html │ ├── browser.html │ ├── ledger │ │ ├── browser.js │ │ ├── main.js │ │ ├── node.js │ │ └── webpack.config.js │ ├── name-claim-queue.js │ ├── node-unhandled-exception.js │ ├── node.cjs │ ├── node.js │ ├── node.ts │ ├── typescript │ │ ├── main.ts │ │ ├── package.json │ │ ├── run.sh │ │ └── tsconfig.json │ └── vue-cli-4-autorest │ │ ├── babel.config.js │ │ ├── package.json │ │ ├── src │ │ └── main.js │ │ └── vue.config.js ├── examples.sh ├── index.ts ├── integration │ ├── AeSdk.ts │ ├── AeSdkMethods.ts │ ├── Middleware.ts │ ├── MiddlewareSubscriber.ts │ ├── account-generalized.ts │ ├── accounts.ts │ ├── aens.ts │ ├── chain.ts │ ├── channel-contracts.ts │ ├── channel-other.ts │ ├── channel-utils.ts │ ├── channel.ts │ ├── compiler.ts │ ├── contract-aci.ts │ ├── contract.ts │ ├── contracts │ │ ├── Includes.aes │ │ ├── Includes.json │ │ ├── Interface.aes │ │ └── lib │ │ │ ├── DecrementInterface.aes │ │ │ ├── Library.aes │ │ │ └── Sublibrary.aes │ ├── delegation.ts │ ├── index.ts │ ├── node.ts │ ├── oracle.ts │ ├── paying-for.ts │ ├── reset-middleware.ts │ ├── rpc.ts │ ├── transaction.ts │ ├── txVerification.ts │ ├── typed-data.ts │ └── ~execution-cost.ts ├── unit │ ├── ae-sdk.ts │ ├── aens.ts │ ├── amount-formatter.ts │ ├── bytes.ts │ ├── crypto.ts │ ├── delegation.ts │ ├── entry-packing.ts │ ├── hd-wallet.ts │ ├── jwt.ts │ ├── ledger.ts │ ├── memory-account.ts │ ├── metamask.ts │ ├── mnemonic.ts │ ├── mptree.ts │ ├── pretty-numbers.ts │ ├── schema.ts │ ├── semver-satisfies.ts │ ├── string.ts │ ├── tx.ts │ └── utils.ts └── utils.ts ├── tooling ├── autorest │ ├── compiler-prepare.js │ ├── compiler.yaml │ ├── middleware-prepare.js │ ├── middleware.yaml │ ├── node.yaml │ └── postprocessing.js ├── docs │ ├── examples-to-md.js │ └── overrides │ │ └── main.html ├── eslint-rules │ └── tsdoc-syntax.cjs ├── fetch-aesophia-cli.js ├── fetch-metamask.js ├── generate-schema.ts └── restore-file.js ├── tsconfig.eslint.json ├── tsconfig.json ├── tsconfig.src.json ├── tsdoc.json └── webpack.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Please tell us about your environment:** 27 | 28 | - Node Version: v0.0.0 29 | - Protocol Version: 1 30 | - Compiler version: v0.0.0 31 | - VM Version: fate | fate2 32 | - SDK Version: v0.0.0 33 | - Python version: v3.7.0 34 | 35 | **Other information** (e.g. detailed explanation, stack traces, related issues, suggestions how to fix, links for us to have context, eg. forum, telegram, etc) 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: feature 6 | assignees: '' 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: CodeQL 2 | 3 | on: 4 | push: 5 | branches: [develop, master] 6 | pull_request: 7 | branches: [develop] 8 | schedule: 9 | - cron: 59 6 * * 2 10 | 11 | jobs: 12 | analyze: 13 | name: Analyze 14 | runs-on: ubuntu-latest 15 | permissions: 16 | actions: read 17 | contents: read 18 | security-events: write 19 | 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | language: [javascript] 24 | 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v4 28 | 29 | - name: Initialize CodeQL 30 | uses: github/codeql-action/init@v3 31 | with: 32 | languages: ${{ matrix.language }} 33 | queries: +security-and-quality 34 | 35 | - name: Autobuild 36 | uses: github/codeql-action/autobuild@v3 37 | 38 | - name: Perform CodeQL Analysis 39 | uses: github/codeql-action/analyze@v3 40 | with: 41 | category: /language:${{ matrix.language }} 42 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Build and publish docs 2 | on: 3 | pull_request: 4 | push: 5 | branches: [develop] 6 | release: 7 | types: [released] 8 | jobs: 9 | main: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | with: 14 | fetch-depth: 0 15 | - uses: actions/setup-python@v5 16 | with: 17 | python-version: 3.x 18 | cache: pip 19 | - uses: actions/setup-node@v4 20 | with: 21 | node-version: 20.x 22 | cache: npm 23 | - run: pip3 install -r docs/requirements.txt 24 | - run: git config --global user.email "github-action@users.noreply.github.com" 25 | - run: git config --global user.name "GitHub Action" 26 | - if: github.event_name == 'pull_request' 27 | run: mkdocs build 28 | - if: github.event_name == 'push' 29 | run: mike deploy --push develop 30 | - if: github.event_name == 'release' 31 | run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV 32 | - if: github.event_name == 'release' 33 | run: mike deploy --push --update-aliases $RELEASE_VERSION latest 34 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Test & build 2 | on: 3 | push: 4 | branches: [master, develop] 5 | pull_request: 6 | jobs: 7 | main: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - run: sudo apt update && sudo apt install --no-install-recommends erlang 11 | - uses: actions/checkout@v4 12 | with: 13 | fetch-depth: 100 14 | - uses: actions/setup-node@v4 15 | with: 16 | node-version: 20.x 17 | cache: npm 18 | - run: npm ci 19 | - name: Run Commitlint 20 | if: github.event_name == 'pull_request' 21 | env: 22 | HEAD: ${{ github.event.pull_request.head.sha }} 23 | BASE: ${{ github.event.pull_request.base.sha }} 24 | run: npx commitlint --from $BASE --to $HEAD --verbose 25 | - run: npm run lint 26 | - run: npm run docs:examples && npm run docs:api && ./docs/build-assets.sh 27 | if: contains(github.event.pull_request.title, 'Release') 28 | - run: docker compose up -d --wait --quiet-pull 29 | - run: npx c8 npm test 30 | - uses: codecov/codecov-action@v5 31 | env: 32 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 33 | - run: docker compose logs 34 | if: always() 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /dist 3 | /es 4 | /docs/api 5 | /docs/examples 6 | /docs/public 7 | __pycache__ 8 | .idea 9 | .vscode 10 | /coverage 11 | /**/package-lock.json 12 | /**/dist 13 | /examples/**/artifacts 14 | .history 15 | .site 16 | site 17 | /src/apis/ 18 | /src/tx/builder/schema.generated.ts 19 | /src/tx/builder/delegation/schema.generated.ts 20 | /src/tx/builder/entry/schema.generated.ts 21 | /tooling/autorest/compiler-swagger.yaml 22 | /tooling/autorest/middleware-openapi.yaml 23 | /test/environment/ledger/browser 24 | /test/assets 25 | /bin 26 | -------------------------------------------------------------------------------- /.mocharc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'node-option': ['import=tsx'], 3 | recursive: true, 4 | extension: '.ts', 5 | timeout: process.env.NETWORK ? '30s' : '6s', 6 | ignore: ['test/charts/**', 'test/emitter/**', 'test/environment/**'], 7 | }; 8 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License (ISC) 2 | Copyright © 2025 aeternity developers 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose 5 | with or without fee is hereby granted, provided that the above copyright notice 6 | and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 10 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 12 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 13 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 14 | THIS SOFTWARE. 15 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | include: [ 7 | // compatibility with create-react-app@4 8 | '@babel/plugin-proposal-nullish-coalescing-operator', 9 | // compatibility with vue-cli-plugin-browser-extension@0.25 10 | '@babel/plugin-proposal-logical-assignment-operators', 11 | // compatibility with @vue/cli@4 12 | '@babel/plugin-proposal-class-properties', 13 | '@babel/plugin-proposal-private-methods', 14 | ], 15 | }, 16 | ], 17 | '@babel/preset-typescript', 18 | ], 19 | plugins: [ 20 | ['@babel/plugin-transform-runtime', { corejs: 3 }], 21 | 'babel-plugin-transform-import-meta', 22 | ], 23 | }; 24 | -------------------------------------------------------------------------------- /babel.esm.config.js: -------------------------------------------------------------------------------- 1 | import config from './babel.config.js'; 2 | 3 | config.presets 4 | .filter((plugin) => Array.isArray(plugin)) 5 | .find(([name]) => name === '@babel/preset-env')[1].modules = false; 6 | 7 | config.plugins.push([ 8 | 'import-globals', 9 | { 10 | Buffer: { moduleName: 'buffer', exportName: 'Buffer' }, 11 | }, 12 | ]); 13 | config.plugins = config.plugins.filter((p) => p !== 'babel-plugin-transform-import-meta'); 14 | 15 | export default config; 16 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'scope-enum': [ 5 | 2, 6 | 'always', 7 | [ 8 | 'account', 9 | 'aens', 10 | 'aepp', 11 | 'chain', 12 | 'channel', 13 | 'compiler', 14 | 'contract', 15 | 'middleware', 16 | 'deps', 17 | 'deps-dev', 18 | 'node', 19 | 'oracle', 20 | 'release', 21 | 'tx-builder', 22 | 'wallet', 23 | ], 24 | ], 25 | }, 26 | ignores: [(message) => /^Bumps \[.+]\(.+\) from .+ to .+\.$/m.test(message)], 27 | }; 28 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | node: 3 | # TODO: switch to master after merging https://github.com/aeternity/aeternity/pull/4303 4 | image: aeternity/aeternity:v7.3.0-rc5-bundle 5 | # TODO: remove 3313 port after merging https://github.com/aeternity/aeternity/pull/4303 6 | ports: [3013:3013, 3113:3113, 3014:3014, 3313:3313] 7 | # TODO: remove after releasing https://github.com/aeternity/aeternity/pull/4292 8 | healthcheck: 9 | interval: 2s 10 | volumes: 11 | - ./docker/aeternity.yaml:/home/aeternity/node/aeternity.yaml 12 | stop_grace_period: 0s 13 | 14 | emitter: 15 | build: test/emitter 16 | depends_on: 17 | node: 18 | condition: service_healthy 19 | 20 | compiler: 21 | image: aeternity/aesophia_http:v8.0.0 22 | ports: [3080:3080] 23 | # TODO: remove after releasing https://github.com/aeternity/aesophia_http/pull/133 24 | healthcheck: 25 | interval: 2s 26 | 27 | middleware: 28 | # TODO: use upstream after solving https://github.com/aeternity/ae_mdw/issues/1758 29 | image: davidyuk/temp:mdw-dev-mode-1.97.1-oas-fix 30 | ports: [4000:4000, 4001:4001, 4013:3013, 4014:3014, 4313:3313] 31 | volumes: 32 | - ./docker/middleware.yaml:/home/aeternity/aeternity.yaml 33 | stop_grace_period: 0s 34 | -------------------------------------------------------------------------------- /docker/aeternity.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://github.com/aeternity/aeternity/raw/master/apps/aeutils/priv/aeternity_config_schema.json 2 | 3 | system: 4 | dev_mode: true 5 | plugins: 6 | # TODO: remove after merging https://github.com/aeternity/aeternity/pull/4303 7 | - name: aeplugin_dev_mode 8 | 9 | http: 10 | internal: 11 | debug_endpoints: true 12 | listen_address: 0.0.0.0 13 | endpoints: 14 | dry-run: true 15 | 16 | websocket: 17 | channel: 18 | listen_address: 0.0.0.0 19 | 20 | chain: 21 | persist: false 22 | hard_forks: 23 | '1': 0 24 | '6': 1 25 | genesis_accounts: 26 | ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E: 10000000000000000000000 27 | -------------------------------------------------------------------------------- /docker/middleware.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://github.com/aeternity/aeternity/raw/master/apps/aeutils/priv/aeternity_config_schema.json 2 | 3 | system: 4 | dev_mode: true 5 | plugins: 6 | - name: aeplugin_dev_mode 7 | 8 | http: 9 | endpoints: 10 | dry-run: true 11 | 12 | websocket: 13 | channel: 14 | listen_address: 0.0.0.0 15 | 16 | dev_mode: 17 | auto_emit_microblocks: true 18 | 19 | chain: 20 | persist: false 21 | hard_forks: 22 | '1': 0 23 | '6': 1 24 | genesis_accounts: 25 | ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E: 10000000000000000000000 26 | 27 | # TODO: remove after solving https://github.com/aeternity/ae_mdw/issues/1760 28 | fork_management: 29 | network_id: ae_dev 30 | 31 | # TODO remove after solving https://github.com/aeternity/ae_mdw/issues/1760#issuecomment-2102872638 32 | mining: 33 | beneficiary: ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E 34 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | -------------------------------------------------------------------------------- /docs/build-assets.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | [ ! -d "node_modules" ] && npm i 5 | npm run docs:examples 6 | npm run docs:api 7 | 8 | # TODO: revisit --ignore-scripts after solving https://github.com/npm/cli/issues/4202 9 | perl -i -pe 's/"prepare"/"rem-prepare"/g' package.json 10 | rm -rf docs/examples/browser 11 | mkdir -p docs/examples/browser 12 | 13 | echo Build example aepp 14 | cd ./examples/browser/aepp 15 | npm i 16 | VUE_APP_WALLET_URL=../wallet-iframe/ PUBLIC_PATH=./ npm run build -- --report 17 | mv dist/ ../../../docs/examples/browser/aepp 18 | 19 | echo Build example wallet-iframe 20 | cd ../wallet-iframe 21 | npm i 22 | VUE_APP_AEPP_URL=../aepp/ PUBLIC_PATH=./ npm run build -- --report 23 | mv dist/ ../../../docs/examples/browser/wallet-iframe 24 | 25 | echo Build example wallet-web-extension 26 | cd ../wallet-web-extension 27 | npm i 28 | NODE_OPTIONS=--openssl-legacy-provider npm run build -- --report 29 | mkdir ../../../docs/examples/browser/wallet-web-extension/ 30 | mv artifacts/wallet-web-extension-v0.1.0-production.zip ../../../docs/examples/browser/wallet-web-extension/packed.zip 31 | mv dist/report.html ../../../docs/examples/browser/wallet-web-extension/report.html 32 | 33 | echo Build example tools 34 | cd ../tools 35 | npm i 36 | npm run build 37 | mv dist/ ../../../docs/examples/browser/tools 38 | 39 | cd ../../.. 40 | perl -i -pe 's/"rem-prepare"/"prepare"/g' package.json 41 | -------------------------------------------------------------------------------- /docs/compatibility.md: -------------------------------------------------------------------------------- 1 | # Compatibility Table 2 | 3 | This package is expected to work in these environments: 4 | 5 | | Environment | Comment | 6 | | ------------------------------------- | ----------------------------------------------------------------------------- | 7 | | nodejs>=18.19 | | 8 | | Browser using script tag, umd | | 9 | | webpack@4 | requires a fix to work with mjs build [webpack-4] | 10 | | webpack@5 | | 11 | | @vue/cli@4 (webpack@4) | requires aliases to ESM versions of autorest deps [vue-cli4] | 12 | | @vue/cli@5 (webpack@5) | | 13 | | vue@3 | AeSdk, Contract instances can't be reactive [vue-3] | 14 | | create-react-app@4 (webpack@4) | mjs build is not compatible with webpack@4 [cra-webpack-4] | 15 | | create-react-app@5 (webpack@5) | | 16 | | create-react-native-app@3 (webpack@4) | mjs build is not compatible with webpack@4 [cra-webpack-4] | 17 | | meteor@2 | | 18 | | jest@27.5.1 | requires an environment where Buffer is instanceof Uint8Array [jest] | 19 | | typescript>=4.8 | requires `tsconfig.json` adjustments [typescript] | 20 | | vite@3 | requires `build.target: 'es2020'` and `bigint: true` in vite.config.js [vite] | 21 | 22 | [webpack-4]: https://github.com/webpack/webpack/issues/7482#issuecomment-394884837 23 | [cra-webpack-4]: https://github.com/aeternity/aepp-sdk-js/issues/1529 24 | [jest]: https://github.com/facebook/jest/issues/4422#issuecomment-770274099 25 | [typescript]: README.md#typescript-projects 26 | [vue-cli4]: README.md#vue-cli4 27 | [vue-3]: README.md#vue3 28 | [vite]: https://github.com/vitejs/vite/issues/9062#issuecomment-1202167352 29 | -------------------------------------------------------------------------------- /docs/guides/build-wallet.md: -------------------------------------------------------------------------------- 1 | # How to build a wallet 2 | 3 | This guide shows how to build either an **WebExtension Wallet** or a **iFrame-based Wallet**. 4 | 5 | ## WebExtension wallet 6 | 7 | The full implementation of this example can be found here: 8 | 9 | - [WebExtension Wallet Example](https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/browser/wallet-web-extension) 10 | 11 | Note: 12 | 13 | - If you want to see a more advanced implementation you can take a look into the repository of the [Superhero Wallet](https://github.com/aeternity/superhero-wallet) 14 | 15 | ### 1. Create bridge between extension and page 16 | 17 | First you need to create a bridge between your extension and the page. This can be done as follows: 18 | 19 | https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/browser/wallet-web-extension/src/content-script.js#L1-L30 20 | 21 | ### 2. Initialize `AeSdkWallet` class 22 | 23 | Then you need to initialize `AeSdkWallet` class in your extension and subscribe for new `runtime` connections. 24 | After the connection is established you can share the wallet details with the application. 25 | 26 | https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/browser/wallet-web-extension/src/background.js#L1-L163 27 | 28 | ## iFrame-based Wallet 29 | 30 | The **iFrame-based** approach works similar to the **WebExtension** approach except that the `connectionProxy` in between isn't needed. 31 | 32 | You can take a look into the implementation of the following example to see how it works: 33 | 34 | - [iFrame-based Wallet Example](https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/browser/wallet-iframe) 35 | -------------------------------------------------------------------------------- /docs/guides/connect-aepp-to-wallet.md: -------------------------------------------------------------------------------- 1 | # Connect an æpp to a wallet 2 | 3 | This guide describes the 4 steps that are necessary to connect your application to a wallet using the RPC API. 4 | 5 | ## Prerequisites 6 | 7 | - Install [Superhero Wallet extension](https://wallet.superhero.com/) for simplicity of example. 8 | You can build your own wallet in the next example 9 | 10 | ## 1. Specify imports and constants 11 | 12 | 13 | 14 | https://github.com/aeternity/aepp-sdk-js/blob/f60d1b8a1124b32781769342e4941c8dacf6ad53/examples/browser/aepp/src/StoreAeSdkPlugin.js#L1-L5 15 | 16 | ## 2. Initialize the `AeSdkAepp` class 17 | 18 | https://github.com/aeternity/aepp-sdk-js/blob/f60d1b8a1124b32781769342e4941c8dacf6ad53/examples/browser/aepp/src/StoreAeSdkPlugin.js#L34-L49 19 | 20 | ## 3. Scan for wallets and connect to a wallet 21 | 22 | https://github.com/aeternity/aepp-sdk-js/blob/f60d1b8a1124b32781769342e4941c8dacf6ad53/examples/browser/aepp/src/Connect.vue#L66-L85 23 | 24 | Alternatively, aepp can request wallet to share node url it connected to. If agreed, then aepp can 25 | connect to the wallet's node. 26 | 27 | ```js 28 | await this.aeSdk.connectToWallet(wallet.getConnection(), { 29 | connectNode: true, 30 | name: 'wallet-node', 31 | select: true, 32 | }); 33 | ``` 34 | 35 | It can be used to 36 | 37 | - improve responsiveness by connecting to the exact node that wallet uses; 38 | - allow to connect aepps to private/development networks without changing their configuration; 39 | - simplify configuration on aepp side. 40 | 41 | Note: 42 | 43 | - The steps above are snippets taken from the full implementation of 44 | the [Simple æpp](https://github.com/aeternity/aepp-sdk-js/blob/f60d1b8a1124b32781769342e4941c8dacf6ad53/examples/browser/aepp) 45 | -------------------------------------------------------------------------------- /docs/guides/jwt.md: -------------------------------------------------------------------------------- 1 | # JWT usage 2 | 3 | ## Generating JWT 4 | 5 | Use `signJwt` to generate a JWT signed by an account provided in arguments. 6 | 7 | ```ts 8 | import { AccountMemory, signJwt } from '@aeternity/aepp-sdk'; 9 | 10 | const account = AccountMemory.generate(); 11 | const payload = { test: 'data' }; 12 | const jwt = await signJwt(payload, account); 13 | ``` 14 | 15 | Provide `sub_jwk: undefined` in payload to omit signer public key added by default. 16 | Do it to make JWT shorter. 17 | 18 | ```ts 19 | const jwt = await signJwt({ test: 'data', sub_jwk: undefined }, account); 20 | ``` 21 | 22 | Or if you using a different way to encode a signer address. 23 | 24 | ```ts 25 | const payload = { 26 | test: 'data', 27 | sub_jwk: undefined, 28 | address: 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E', 29 | }; 30 | const jwt = await signJwt(payload, account); 31 | ``` 32 | 33 | ## Verifying JWT 34 | 35 | Let's assume we got a JWT as string. Firstly we need to ensure that it has the right format. 36 | 37 | ```ts 38 | import { isJwt, ensureJwt } from '@aeternity/aepp-sdk'; 39 | 40 | if (!isJwt(jwt)) throw new Error('Invalid JWT'); 41 | // alternatively, 42 | ensureJwt(jwt); 43 | ``` 44 | 45 | After that we can pass JWT to other SDK's methods, for example to get JWT payload and signer address 46 | in case JWT has the signer public key included in `"sub_jwk"`. 47 | 48 | ```ts 49 | import { unpackJwt } from '@aeternity/aepp-sdk'; 50 | 51 | const { payload, signer } = unpackJwt(jwt); 52 | console.log(payload); // { test: 'data', sub_jwk: { ... } } 53 | console.log(signer); // 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E' 54 | ``` 55 | 56 | `unpackJwt` will also check the JWT signature in this case. 57 | 58 | Alternatively, if `"sub_jwk"` is not included then we can provide signer address to `unpackJwt`. 59 | 60 | ```ts 61 | const knownSigner = 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E'; 62 | const { payload, signer } = unpackJwt(jwt, knownSigner); 63 | console.log(payload); // { test: 'data' } 64 | console.log(signer); // 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E' 65 | ``` 66 | 67 | If we need to a get signer address based on JWT payload then we need to unpack it without checking 68 | the signature. Don't forget to check signature after that using `verifyJwt`. 69 | 70 | ```ts 71 | import { verifyJwt } from '@aeternity/aepp-sdk'; 72 | 73 | const { payload, signer } = unpackJwt(jwt); 74 | console.log(payload); // { address: 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E' } 75 | console.log(signer); // undefined 76 | if (!verifyJwt(jwt, payload.address)) throw new Error('JWT signature is invalid'); 77 | ``` 78 | -------------------------------------------------------------------------------- /docs/guides/low-vs-high-usage.md: -------------------------------------------------------------------------------- 1 | # Low vs High level API 2 | 3 | ## Interactions 4 | 5 | `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. 6 | 7 | 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. 8 | 9 | ### Node API 10 | 11 | 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][node]) a basically a mapping of all node endpoints as functions. 12 | 13 | [a REST API]: https://api-docs.aeternity.io/ 14 | [OpenAPI document]: https://mainnet.aeternity.io/api?oas3 15 | [node]: https://sdk.aeternity.io/v14.1.0/api/classes/Node.html 16 | 17 | 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. 18 | 19 | ### Transaction builder 20 | 21 | Any blockchain state change requires signing a transaction. Transaction should be built according to the [protocol]. SDK implements it in [`buildTx`][buildTx], [`buildTxAsync`][buildTxAsync], and [`unpackTx`][unpackTx]. [`buildTxAsync`][buildTxAsync] requires fewer arguments than [`buildTx`][buildTx], but it expects the node instance provided in arguments. 22 | 23 | [protocol]: https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/serializations.md#accounts-version-1-basic-accounts 24 | [buildTx]: https://sdk.aeternity.io/v14.1.0/api/functions/buildTx.html 25 | [buildTxAsync]: https://sdk.aeternity.io/v14.1.0/api/functions/buildTxAsync.html 26 | [unpackTx]: https://sdk.aeternity.io/v14.1.0/api/functions/unpackTx.html 27 | 28 | ## High-level SDK usage (preferable) 29 | 30 | Example spend call, using æternity's SDK abstraction: 31 | 32 | https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/node/_api-high-level.js#L1-L18 33 | 34 | ## Low-level SDK usage 35 | 36 | The same spend execution, but using low-level SDK functions: 37 | 38 | https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/node/_api-low-level.js#L1-L19 39 | -------------------------------------------------------------------------------- /docs/guides/migration/7.md: -------------------------------------------------------------------------------- 1 | # Migration to 7.0.0 2 | 3 | This guide describes the process of migrating to SDK version 7.0.0 4 | 5 | ## Step 1 6 | 7 | SDK will not accept `url`, `internalUrl` init arguments anymore: 8 | 9 | #### Before 10 | 11 | ```js 12 | Universal({ 13 | url, 14 | internalUrl, 15 | }); 16 | ``` 17 | 18 | #### After 19 | 20 | ```js 21 | const nodeInstance = await Node({ url, internalUrl }); 22 | Universal({ 23 | nodes: [{ name: 'testnet', instance: nodeInstance }], 24 | }); 25 | ``` 26 | 27 | ## Step 2 28 | 29 | Remove deprecated function `setKeypair` 30 | `SDK` will not accept `keypair` init argument anymore: 31 | 32 | #### Before 33 | 34 | ```js 35 | Universal({ keypair }); 36 | ``` 37 | 38 | #### After 39 | 40 | ```js 41 | Universal({ 42 | accounts: [MemoryAccount({ keypair })], 43 | }); 44 | ``` 45 | 46 | ## Step 3 47 | 48 | Change all of `AENS` method's first argument from `nameId` to `name` 49 | 50 | ### Before 51 | 52 | ```js 53 | const client = Universal({ ... }) 54 | 55 | await client.aensUpdate('cm_ad1wdsa...', ...) 56 | await client.aensTransfer('cm_ad1wdsa...', ...) 57 | await client.aensRevoke('cm_ad1wdsa...', ...) 58 | ``` 59 | 60 | ### After 61 | 62 | ```js 63 | const client = Universal({ ... }) 64 | 65 | await client.aensUpdate('testname.chain', ...) 66 | await client.aensTransfer('testname.chain', ...) 67 | await client.aensRevoke('testname.chain', ...) 68 | ``` 69 | 70 | ## Other Breaking Changes 71 | 72 | - Add new compiler `methods` to RPC `communication` (base-app update required) 73 | - Drop compiler version to `version >= 4.0.0 && version < 5.0.0` 74 | - Change node compatibility range to `node >= 5.0.0 && node < 6.0.0` 75 | - Always `verify` transactions before sending them to the node (can be disabled using the option `verify: false`) 76 | -------------------------------------------------------------------------------- /docs/guides/migration/9.md: -------------------------------------------------------------------------------- 1 | # Migration to 9.0.0 2 | 3 | This guide describes all breaking changes introduced with `v9.0.0`. 4 | 5 | ## drop `waitMined` static method 6 | 7 | If you used it like 8 | 9 | ```js 10 | const sdk = await Universal({ ... }) 11 | sdk.waitMined(false) 12 | ``` 13 | 14 | then you have to rewrite it using Stamp composition 15 | 16 | ```js 17 | const sdk = await Universal.compose({ 18 | deepProps: { Ae: { defaults: { waitMined: false } } } 19 | })({ ... }) 20 | ``` 21 | 22 | or pass it to specific methods, like 23 | 24 | ```js 25 | sdk.spend(amount, receiver, { waitMined: false }); 26 | ``` 27 | 28 | or even 29 | 30 | ```js 31 | const sdk = await Universal({ ... }) 32 | sdk.deepProps({ Ae: { defaults: { waitMined: false } } }) 33 | ``` 34 | 35 | ## drop `assertedType`, use `decode` instead 36 | 37 | If you used it like 38 | 39 | ```js 40 | const payload = Crypto.decodeBase64Check(Crypto.assertedType('tx_...', 'tx')); 41 | ``` 42 | 43 | then you have to rewrite it using `decode` method 44 | 45 | ```js 46 | const payload = TxBuilderHelper.decode('tx_...', 'tx'); 47 | ``` 48 | 49 | ## **validator:** recursive validator, simplify schema 50 | 51 | Instead of `TransactionValidator` stamp use `verifyTransaction` function. The function accepts 52 | a transaction, and a Node instance for validation (instead of network id), it doesn't return 53 | an unpacked transaction anymore, just an array of errors. Each error contains a verbose `message` 54 | (`msg` before), unique `key` (for easy comparison), `checkedKeys` array (`txKey` before). Using 55 | `node` instead of `networkId` allows to ensure transaction validation, so warnings are errors 56 | now (`type` field removed). 57 | 58 | `SCHEMA` doesn't contain validation schema anymore. This wasn't supposed to be used by external 59 | developers. 60 | 61 | ## simplify buildTxHash helper 62 | 63 | If you used `buildHash` like 64 | 65 | ```js 66 | const hash = TxBuilderHelper.buildHash('xx', Buffer.from([1, 2, 3]), { raw: true }); 67 | ``` 68 | 69 | then use 70 | 71 | ```js 72 | const hash = Crypto.hash(Buffer.from([1, 2, 3])); 73 | ``` 74 | 75 | If you used it with a falsy `raw` then 76 | 77 | ```js 78 | const hash = TxBuilderHelper.encode(Crypto.hash(Buffer.from([1, 2, 3])), 'xx'); 79 | ``` 80 | 81 | `buildTxHash` don't have `raw` switch anymore, it returns `th_`-encoded string in all cases, 82 | but it still accepts transactions as a string and as a buffer. 83 | 84 | ## enable verification in deep props instead of extra variable 85 | 86 | If you were passing `verifyTx: false` to sdk factory then use `verify: false` instead. 87 | -------------------------------------------------------------------------------- /docs/guides/paying-for-tx.md: -------------------------------------------------------------------------------- 1 | # PayingForTx (Meta-Transactions) 2 | 3 | ## Introduction 4 | 5 | This guide explains you how to perform a `PayingForTx` (also known as meta-transaction) using the SDK. 6 | 7 | It is a very powerful and efficient solution that is crucial for onboarding new users into you ecosystem. By making use of the `PayingForTx` you will be able to cover the fees of your users. 8 | 9 | ## How it works 10 | 11 | Typically somebody that you want to pay the transaction for (e.g. a new user of your decentralized aepp) signs the **inner transaction** (e.g. of type `ContractCallTx`) with a **specific signature** that is used for inner transactions. 12 | 13 | You can then collect the signed inner transaction, wrap it into a `PayingForTx` and broadcast it to the network. 14 | 15 | ## Usage examples 16 | 17 | We provided following two NodeJS examples which you can take a look at: 18 | 19 | - [InnerTx: ContractCallTx](https://sdk.aeternity.io/v14.1.0/examples/node/paying-for-contract-call-tx/) 20 | - [InnerTx: SpendTx](https://sdk.aeternity.io/v14.1.0/examples/node/paying-for-spend-tx/) 21 | 22 | Note: 23 | 24 | - A `PayingForTx` can wrap **any kind** of other [transaction type](https://docs.aeternity.com/developer-documentation/protocol/consensus#transactions-1) supported by the protocol as inner transaction. 25 | 26 | ## UseCases 27 | 28 | - Game developers that want to quickly onboard new users. 29 | - Governance aepps that want people to vote on important proposals without having them to pay anything. 30 | - Custodians that want to offer an additional services to cover the transaction fees of their clients. 31 | - ... many more! 32 | -------------------------------------------------------------------------------- /docs/guides/typed-data.md: -------------------------------------------------------------------------------- 1 | # Typed data hashing and signing 2 | 3 | ## Common structure 4 | 5 | The whole idea is heavily inspired by [EIP-712](https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator). To get a signature needed to calculate `hash(hash(domain), hash(aci), hash(data))`. 6 | 7 | `hash` function is `blake2b`. 8 | 9 | `domain` is a record containing not required properties: 10 | 11 | - `name` as string, 12 | - `version` as integer, 13 | - `networkId` as string, 14 | - `contractAddress` as ct-encoded string. 15 | 16 | `aci` is part of a complete contract ACI. It defines a type of data to sign. For example, the ACI 17 | 18 | ```json 19 | { 20 | "record": [ 21 | { "name": "foo", "type": "string" }, 22 | { "name": "bar", "type": "int" } 23 | ] 24 | } 25 | ``` 26 | 27 | corresponds to the data 28 | 29 | ```json 30 | { "foo": "test", "bar": 42 } 31 | ``` 32 | 33 | `domain` and `data` are fate-encoded before hashing. `aci` is prepared for hashing according to [RFC8785](https://tools.ietf.org/html/rfc8785). 34 | 35 | ## Implementation 36 | 37 | - [AccountBase:signTypedData](https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/src/account/Base.ts#L64-L71) — calculates signature, supported in AccountMemory and in aepp-wallet connection; 38 | - [hashTypedData](https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/src/utils/typed-data.ts#L87-L101) — calculates the overall hash of typed data to sign; 39 | - [hashJson](https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/src/utils/typed-data.ts#L11-L13) — deterministic hashing of an arbitrary JS value, used to calculate `hash(aci)`; 40 | - [hashDomain](https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/src/utils/typed-data.ts#L58-L82) — use for debugging or to prepare the hash value for smart contract. 41 | 42 | ## Examples 43 | 44 | - [signing and verifying on aepp side](https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/browser/aepp/src/TypedData.vue) 45 | - [signing confirmation on wallet side](https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/browser/wallet-iframe/src/App.vue#L168-L176) 46 | - [verifying a signature on contract side](https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/test/integration/typed-data.ts#L76-L106) 47 | -------------------------------------------------------------------------------- /docs/hooks.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import re 3 | import urllib.request 4 | 5 | def pre_build(**kwargs): 6 | subprocess.run(['./docs/build-assets.sh'], check=True) 7 | 8 | def replacer(match): 9 | filename = f"{match.group('filename')}.{match.group('extension')}" 10 | url = f"https://raw.githubusercontent.com/{match.group('user')}/{match.group('commit')}/{filename}" 11 | code = urllib.request.urlopen(url).read().decode('utf-8') 12 | extension = 'js' if match.group('extension') == 'vue' else match.group('extension') 13 | return '\n'.join( 14 | [f'``` {extension} title="{filename}"'] + 15 | code.split('\n')[int(match.group('begin')) - 1:int(match.group('end'))] + 16 | ['```', f'View at [GitHub]({match.group(0)})'] 17 | ) 18 | 19 | def page_markdown(markdown, **kwargs): 20 | return re.sub( 21 | re.compile( 22 | r'^https://github.com/(?P[\w/\-]+)/blob/(?P[0-9a-f]+)/(?P[\w\d\-/\.]+)\.(?P\w+)#L(?P\d+)-L(?P\d+)$', 23 | re.MULTILINE, 24 | ), 25 | replacer, 26 | markdown, 27 | ) 28 | -------------------------------------------------------------------------------- /docs/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aeternity/aepp-sdk-js/4024d42a82439203ff60cfb96a18498970ce7ef3/docs/images/favicon.png -------------------------------------------------------------------------------- /docs/quick-start.md: -------------------------------------------------------------------------------- 1 | # Quick Start 2 | 3 | In this example we will send 1 _AE_ coin from one account to another. 4 | For more specific information on setups with Frameworks and TypeScript, please refer to the [installation instructions](./README.md). 5 | 6 | ## 1. Specify imports 7 | 8 | For the following snippets in the guide you need to specify multiple imports. 9 | 10 | ```js 11 | const { AeSdk, AccountMemory, Node } = require('@aeternity/aepp-sdk'); 12 | ``` 13 | 14 | ## 2. Create a sender account 15 | 16 | ```js 17 | const sender = AccountMemory.generate(); 18 | console.log('Sender address:', sender.address); 19 | console.log('Sender secret key:', sender.secretKey); 20 | ``` 21 | 22 | ## 3. Get some _AE_ using the Faucet 23 | 24 | To receive some _AE_ you can use the [Faucet](https://faucet.aepps.com/). Just paste sender's address, hit `Top UP` and you'll immediately get some test coins. 25 | 26 | ## 4. Interact with the æternity blockchain 27 | 28 | This example shows: 29 | 30 | - how to create an instance of the SDK using the `AeSdk` class 31 | - how to spend (send) 1 _AE_ from the account the SDK instance was initialized with to some other AE address 32 | 33 | ```js 34 | const NODE_URL = 'https://testnet.aeternity.io'; 35 | // replace with the generated secretKey from step 2 36 | const sender = new AccountMemory(''); 37 | 38 | (async function () { 39 | const node = new Node(NODE_URL); 40 | const aeSdk = new AeSdk({ 41 | nodes: [{ name: 'testnet', instance: node }], 42 | accounts: [sender], 43 | }); 44 | 45 | // spend one AE 46 | await aeSdk.spend(1e18, ''); 47 | // replace , Ideally you use address from Superhero Wallet you have created before 48 | })(); 49 | ``` 50 | 51 | Note: 52 | 53 | - You may remove code from Step 2 as this serves only for one-time creation 54 | - The `spend` function expects the amount to be spent in `aettos` (the smallest possible unit, 1 _AE_ equal to 1 000 000 000 000 000 000 `aettos`) 55 | - See [Testnet Explorer](https://testnet.aescan.io/) and track your transactions 56 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocs==1.6.1 2 | mkdocs-simple-hooks==0.1.5 3 | mkdocs-material==9.6.12 4 | mike==2.1.3 5 | -------------------------------------------------------------------------------- /docs/tutorials/vuejs/helloworld-blockheight.md: -------------------------------------------------------------------------------- 1 | # Vue.js HelloWorld 2 | 3 | This tutorial shows you how to use the SDK in your Vue.js application. 4 | You will replace the content of the default `HelloWorld` component and display the current block height of the æternity testnet. 5 | 6 | ## 1. Install Vue.js 7 | 8 | ```bash 9 | npm install -g @vue/cli 10 | ``` 11 | 12 | ## 2. Create a new Vue.js project 13 | 14 | ```bash 15 | vue create my-project 16 | ``` 17 | 18 | ## 3. Switch to the folder of your Vue.js project 19 | 20 | ```bash 21 | cd my-project 22 | ``` 23 | 24 | ## 4. Install the SDK 25 | 26 | ```bash 27 | npm install @aeternity/aepp-sdk 28 | ``` 29 | 30 | ## 5. Modify the HelloWorld component 31 | 32 | ```js 33 | 34 | 35 | 59 | ``` 60 | 61 | ## 6. Run the application 62 | 63 | ```bash 64 | npm run serve 65 | ``` 66 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # ⚡ Examples 2 | 3 | This folder contains examples of code samples that you can run autonomously. 4 | Create a [new issue](https://github.com/aeternity/aepp-sdk-js/issues/new) to suggest another example. 5 | 6 | ## Wallet connection 7 | 8 | ### Connect to a wallet 9 | 10 | - [æpp](browser/aepp) (VueJS) 11 | 12 | ### Build a wallet 13 | 14 | - [iframe-based Wallet](browser/wallet-iframe) (VueJS) 15 | - [Wallet WebExtension](browser/wallet-web-extension) 16 | 17 | ## NodeJS 18 | 19 | 1. [Contract interaction](node/contract-interaction.js) 20 | 2. [Transfer AE](node/transfer-ae.js) 21 | 3. [Paying for spend tx](node/paying-for-spend-tx.js) 22 | 4. [Paying for contract call tx](node/paying-for-contract-call-tx.js) 23 | 5. [Dry-run using debug endpoint](node/dry-run-using-debug-endpoint.js) 24 | 6. [Oracle](node/oracle.js) 25 | -------------------------------------------------------------------------------- /examples/browser/README.md: -------------------------------------------------------------------------------- 1 | # How to connect wallet to æpp using æternity's JS SDK 2 | 3 | ## Introduction 4 | 5 | In æternity ecosystem, the app that has access to user's private keys and grants other apps 6 | access to them is called wallet. Respectively, the app that is granted access is called aepp. 7 | 8 | This folder has been created to **showcase the æternity SDK integration** to both wallets and aepps. 9 | 10 | ## Setup info 11 | 12 | If you are trying these examples after checking out this repo, 13 | you want to first run `npm install`, from the repo root, to get all the SDK dependencies installed, 14 | and only then, move to individual apps installations. 15 | 16 | ## Available examples 17 | 18 | ### 1. æpp 19 | 20 | The Sample [æpp](aepp) project (Distributed App or dapp) shows how you can create a simple æternity æpp, 21 | dependent on a Wallet, in this case: offering the possibility to work with contracts. 22 | 23 | ### 2. Wallet WebExtension 24 | 25 | The [Wallet WebExtension](wallet-web-extension) example project shows how you can create a simple 26 | æternity wallet as a Chrome/Firefox browser extension. This approach is actively used in 27 | [Superhero Wallet](https://github.com/aeternity/superhero-wallet). 28 | 29 | ### 3. iframe-based wallet 30 | 31 | The [wallet](wallet-iframe) example project shows how you can create a simple æternity wallet 32 | that opens æpps in iframe. This approach is actively used in [Base æpp](https://github.com/aeternity/aepp-base). 33 | -------------------------------------------------------------------------------- /examples/browser/aepp/README.md: -------------------------------------------------------------------------------- 1 | # Sample æpp for contracts 2 | 3 | ## Overview 4 | 5 | This is a sample æpp that compiles contracts using the æternity JavaScript SDK. 6 | 7 | ### How it works 8 | 9 | 1. Choose the wallet example from [examples](..) folder (the simplest is [iframe-based wallet](../wallet-iframe)) 10 | 2. Start the wallet according to its readme 11 | 3. Start this æpp, which will start on port [9001](http://localhost:9001) 12 | 4. Connect this æpp to a choosed wallet according to its readme 13 | 14 | ## Installation and running 15 | 16 | Prerequisite: [refer SDK installation](../README.md#setup-info) 17 | 18 | 1. Install required dependencies with `npm install` 19 | 1. Start the application `npm run serve` 20 | -------------------------------------------------------------------------------- /examples/browser/aepp/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@vue/cli-plugin-babel/preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /examples/browser/aepp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aepp", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "@aeternity/aepp-calldata": "^1.5.1", 11 | "@aeternity/aepp-sdk": "file:../../..", 12 | "@ledgerhq/hw-transport-web-ble": "^6.29.4", 13 | "@ledgerhq/hw-transport-webusb": "^6.29.4", 14 | "buffer": "^6.0.3", 15 | "core-js": "^3.32.1", 16 | "tailwindcss": "^2.2.19", 17 | "vue": "^3.3.4", 18 | "vuex": "^4.1.0" 19 | }, 20 | "devDependencies": { 21 | "@vue/cli-plugin-babel": "~5.0.8", 22 | "@vue/cli-service": "~5.0.8", 23 | "sass": "^1.66.1", 24 | "sass-loader": "^13.3.2" 25 | }, 26 | "peerDependencies": { 27 | "webpack": "^5.0.0" 28 | }, 29 | "browserslist": [ 30 | "> 1%", 31 | "last 2 versions", 32 | "not dead", 33 | "not ie 11" 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /examples/browser/aepp/public/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/browser/aepp/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Simple æpp 10 | 11 | 12 | 18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /examples/browser/aepp/public/webmanifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Simple æpp", 3 | "short_name": "Simple æpp", 4 | "icons": [ 5 | { 6 | "src": "./icon.svg", 7 | "type": "image/svg" 8 | } 9 | ], 10 | "aeternity_network_ids": ["ae_mainnet", "ae_uat"], 11 | "description": "Simple æpp description. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", 12 | "categories": ["finance"], 13 | "author": "aeternity developers", 14 | "author_url": "https://github.com/aeternity/aepp-sdk-js" 15 | } 16 | -------------------------------------------------------------------------------- /examples/browser/aepp/src/App.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 54 | 55 |