# Migration to 12.0.0

This guide describes all breaking changes introduced with `v12.0.0`.

## General

#### `Universal`, `RpcAepp`, `RpcWallet`, `Ae` stamps are removed

Use `AeSdk`, `AeSdkAepp`, `AeSdkWallet`, `AeSdbBase` accordingly.\
For example:

```diff
-import { Universal } from '@aeternity/aepp-sdk'
+import { AeSdk } from '@aeternity/aepp-sdk'

-const aeSdk = await Universal(options)
+const aeSdk = new AeSdk(options)
```

#### `Node`, `RpcClient`, `BrowserWindowMessage` classes are using private fields

Accessing private fields through `Proxy` will lead to "TypeError: attempted to set private\
field on non-instance" ([tc39](https://github.com/tc39/proposal-class-fields/issues/106)).\
This may be an issue if you are using aepp-sdk with Vue\@3, because Vue\@3 introduced reactivity based\
on `Proxy` class ([Vue docs](https://vuejs.org/guide/extras/reactivity-in-depth.html#how-reactivity-works-in-vue)).\
Avoid the above error by not making instances of these classes reactive.

#### all combined exports are inlined (`require('@aeternity/aepp-sdk').generateKeyPair()`)

Import the needed utils directly instead of importing a wrapper object firstly.\
For example:

```diff
-import { Crypto } from '@aeternity/aepp-sdk'
+import { generateKeyPair } from '@aeternity/aepp-sdk'

-console.log(Crypto.generateKeyPair())
+console.log(generateKeyPair())
```

#### `AccountBase` and inheritors are classes now

Use `new` to create an instance.

#### `ChainNode`, `Contract`, `Oracle`, `Aens`, `GeneralizedAccount` stamps not exported

Their methods exported instead. Outside of `AeSdkBase` context, they may accept `onAccount`,`onNode`, `onCompiler` options.

## Node and Compiler

#### `Node`, `Compiler` (previously `ContractCompilerHttp`) are classes instead of a stamps

For example:

```diff
import { Node } from '@aeternity/aepp-sdk'

-const node = await Node({ url, ignoreVersion: false })
+const node = new Node(url, { ignoreVersion: false })
```

#### `Node`, `Compiler` doesn't check version on the first request instead of init

Don't handle `new Node(...)` and `new Compiler(...)` as a `Promise`.

#### `getNetworkId` returns a promise

#### `getNetworkId` ignores `force` option

So, it would throw exception in case networkId is not provided. Use `try/catch` instead.

#### `api` is removed in `Node`

Use `node.getBalance` instead of `node.api.getBalance.`

#### static properties are removed in `Node`

Use `node.getStatus()` or `node.getNodeInfo()` to get values of `version`, `revision`,`genesisHash`, `nodeNetworkId`, `consensusProtocolVersion`.

#### `Node` returns BigInts for coin amount fields instead of string or number

#### `Node` not accepts `internalUrl`

`Node` doesn't accepts and stores `internalUrl`, also internal endpoints are not available anymore.\
If necessary, create a wrapper of internal API separately (`swagger-client` package).

#### removed `mempool` method in `Node`

Create a wrapper of internal API by `genSwaggerClient` and use `getPendingTransactions` method\
instead.

#### `compilerVersion` is removed in `Compiler`

Use `compilerApi.aPIVersion()` method instead.

#### `setCompilerUrl` changes compiler URL in sync

Don't handle `aeSdk.setCompilerUrl(...)` as a `Promise`.

#### methods of `Compiler` requires `options` object according to their specification

#### methods of `Compiler` returns and accepts keys named in camelCase instead of snake\_case

## Transaction builder

#### removed methods to generate a transaction of specific type

Use `aeSdk.buildTx(txType, params)` instead.

#### removed ability to generate transaction on the node side

Use `aeSdk.buildTx(txType, params)` instead.

#### `nonce`, `ttl`, `gas` decoded and accepted as numbers instead of strings

#### `gas` renamed to `gasLimit`

Use `gasLimit` instead of `gas` everywhere except for transaction details returned by node.

#### `unpackTx` not accepting transaction as `Buffer`, only as tx-encoded string

Use `unpackTx(encode(tx, 'tx'))` instead.

#### `unpackTx` doesn't have `binary` field in result

Use `require('rlp').decode(unpackTx(tx).rlpEncoded)` instead.

#### **encode:** since the prefix is evaluated by the type itself the required prefix parameter

is no more accepted\
For example:

```diff
-decode('cb_DA6sWJo=', 'cb')
+decode('cb_DA6sWJo=')
```

#### `calculateMinFee` returns BigNumber instead of string

#### Fee helpers not exported anymore (`BASE_GAS`, `GAS_PER_BYTE`, `KEY_BLOCK_INTERVAL`,

`TX_FEE_BASE_GAS`, `TX_FEE_OTHER_GAS`, `calculateFee`, `DEFAULT_FEE`)\
Use a general `calculateMinFee` instead.

#### `buildRawTx`, `calculateTtl` not exported anymore

Use a general `buildTx` method instead.

#### `TX_TYPE` mapped to tag (number) instead of string

Always use `TX_TYPE`. To get type name by tag use `TX_TYPE[tag]`.

#### `OBJECT_ID_TX_TYPE` not exported anymore

Use `TX_TYPE[tag]` instead.

#### `TX_SERIALIZATION_SCHEMA` combined with `TX_DESERIALIZATION_SCHEMA`

Use `TX_SCHEMA[TX_TYPE.*]` instead.

#### Transaction schemas doesn't contain tag anymore

Use `OBJECT_ID_TX_TYPE` to find tag by transaction type.

## AENS

#### `computeBidFee` accepts `startFee`, `increment` as options

#### `NAME_BID_TIMEOUTS` not exposed anymore

Use `computeAuctionEndBlock` function instead.

#### `computeAuctionEndBlock` accepts and returns height as number

#### removed `ensureNameValid`

Use a TypeScript check instead.

#### `name.update`, `name.revoke` doesn't accept address in `onAccount`

Pass an instance of `AccountBase` to `onAccount` option instead.

## Oracle

#### `extendOracleTtl` accepts oracle ttl in `oracleTtlType` and `oracleTtlValue` fields

Use `oracleTtlType` field instead of `type`, and `oracleTtlValue` field instead of `value`.

#### `decode` method of `getQueryObject` removed

Use `decode` function instead.

## Contract

#### `createAensDelegationSignature` first argument not an object

`contractId` accepted as the first argument, `name` should be passed as option to the second one.

#### `createOracleDelegationSignature` first argument not an object

`contractId` accepted as the first argument, `queryId` should be passed as option to the second one.

#### call arguments in `createGeneralizedAccount` is required

Pass an empty array if you need no arguments.

#### `filesystem` option renamed to `fileSystem`

#### Contract instance doesn't accept address in `onAccount`

It should be an instance of `AccountBase` instead.

## Chain

#### removed `balance` method

Use `getBalance` instead.

#### removed `tx` method

Use `node.getTransactionByHash/getTransactionInfoByHash` instead.

#### removed `getTxInfo` method

Use `node.getTransactionInfoByHash` instead.

## Other

#### `getAccountNonce` removed

Use `node.getAccountNextNonce` instead.

#### `AeSdk` doesn't accept array of accounts

Use `aeSdk.addAccount` method instead.

#### `destroyInstance` method removed

It wasn't doing anything, just remove it's usages.

#### `NodePool` is removed

Use `AeSdkBase` or `AeSdk` instead.

#### `AccountMultiple` is removed

Use `AeSdk` instead.

#### `DENOMINATION_MAGNITUDE` not exposed anymore

It is intended for internal use only.

#### The result of `unpackTx` returned instead of `TxObject`

In `txObject` option of `onSign` handler on wallet side.\
In `tx` field of contract call result.

#### `validateKeyObj` removed

Rely on TypeScript checks instead.

#### `deriveKeyUsingArgon2id` removed

Use `argon2-browser` package instead.

#### removed extra implementation of `getAddressFromPriv` in keystore

Use `Crypto.getAddressFromPriv` instead.

#### `genSwaggerClient` removed

Use `swagger-client` package instead.

## Aepp Wallet communication

#### BrowserRuntimeConnection, BrowserWindowMessageConnection are classes

Create instances using new.

#### ContentScriptBridge, WalletDetector rewrited to plain functions

Use `connectionProxy`, `walletDetector` accordingly.

#### **RpcClient:** removed `origin` property

Use `connection` property instead.

#### **RpcClient:** `sendMessage` is a private method

Use `request` or `notify` instead.

#### **RpcClient:** `handlers` parameter is removed

Provide a `methods` parameter instead of `handlers[0]`.\
Provide an `onDisconnect` parameter instead of `handlers[1]`.

#### **RpcClient:** doesn't contain aepp info anymore

Get aepp info in `onConnection` callback, and store somehow to use later.

#### **RpcClient:** doesn't contain `networkId` anymore

On wallet side: assume that all aepps uses the same network as the wallet connected to.\
On aepp side: use `networkId` that wallet provided.\
In case `networkId` is not compatible ask user to switch wallet to a compatible network.

#### RPC helpers are not exposed anymore (`isInIframe`, `sendMessage`, `getHandler`, `message`,

`responseMessage`, `sendResponseMessage`, `isValidAccounts`)\
Use own implementation if needed.

## Aepp

#### `connectToWallet` accepts wallet connection as the first argument

See [connect-aepp-to-wallet.md](/developer-documentation/aepp-sdk-js/docs/guides/connect-aepp-to-wallet.md) for details.

#### `disconnectWallet` runs in sync and `sendDisconnect` arg removed

So, aepp would always send `closeConnection` notification.

#### `sendConnectRequest` removed

Use `connectToWallet` instead.

#### doesn't accept `connection` anymore

Use `connectToWallet` method instead.

#### removed `isConnected`, `isSubscribedAccount` methods

Detect is aepp connected by persistence of `rpcClient` property.

#### `signMessage` returns Buffer by default

Use `returnHex` option to get the previous behaviour.

## Wallet

#### `BrowserRuntimeConnection` requires `port` parameter

Pass `require('webextension-polyfill').runtime.connect()` to it.

#### requires `id`, `type` in params

`id` should be a unique string;`type` should be one of `WALLET_TYPE.window`, `WALLET_TYPE.extension`.

#### `getBrowserAPI` helper removed

Use `webextension-polyfill` package instead.

#### `shareWalletInfo` accepts rpc client id instead of callback

For example:

```diff
const connection = new BrowserRuntimeConnection({ port })
-aeSdk.addRpcClient(connection)
-aeSdk.shareWalletInfo(port.postMessage.bind(port))
+const rpcClientId = aeSdk.addRpcClient(connection)
+aeSdk.shareWalletInfo(rpcClientId)
```

#### `shareNode` argument in accept callback of `onConnection` removed

Just deny the connection if you don't want to share the node url.

#### can't handle specific set of accounts for an app

If you need this feature, create a custom wallet implementation or fill us an issue.

#### `txObject` parameter of `onSign` callback is removed

Use `unpackTx(tx)` on wallet side instead.

#### `rpcClients` in wallet is not exposed anymore

This expected to be used only internally.

#### `onDisconnect` callback on wallet side accepts client id instead of `RpcClient`

Use `sdk.rpcClient[clientId]` to get the corresponding instance of RpcClient.

#### wallet can't selectively notify aepps about selecting/adding account

If you need this feature, create a custom wallet implementation or fill us an issue.

#### wallet can't provide metadata for accounts

If you need this feature, create a custom wallet implementation or fill us an issue.

#### removed `action.accept` in permission callbacks

Return the value you passed to `accept` instead.

#### removed `action.deny` in permission callbacks

Throw instances of `RpcRejectedByUserError` instead.

#### callbacks accept client id, params, and origin


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.aeternity.com/developer-documentation/aepp-sdk-js/docs/guides/migration/12.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
