Skip to content

Commit

Permalink
refactor!: drop functions to generate txs with specific type
Browse files Browse the repository at this point in the history
BREAKING CHANGE: removed methods to generate a transaction of specific type
Use sdk.buildTx(txType, params) instead.
  • Loading branch information
davidyuk committed May 19, 2022
1 parent d10f806 commit 3cf767d
Show file tree
Hide file tree
Showing 17 changed files with 159 additions and 553 deletions.
2 changes: 1 addition & 1 deletion docs/guides/low-vs-high-usage.md
Expand Up @@ -48,7 +48,7 @@ async function spend (amount, recipient) {
})

// builds an unsigned SpendTx using the debug endpoint of the node's API
const spendTx = await aeSdk.spendTx({
const spendTx = await aeSdk.buildTx(TX_TYPE.spend, {
senderId: await aeSdk.address(),
recipientId: recipient,
fee: 18000000000000, // you must provide enough fee
Expand Down
4 changes: 2 additions & 2 deletions examples/node/paying-for-tx-contract-call-tx.js
Expand Up @@ -47,7 +47,7 @@
// ## 1. Specify imports
// You need to import `Universal`, `Node` and `MemoryAccount` [Stamps](https://stampit.js.org/essentials/what-is-a-stamp) from the SDK.
// Additionally you import the `generateKeyPair` utility function to generate a new keypair.
const { Universal, Node, MemoryAccount, generateKeyPair } = require('@aeternity/aepp-sdk')
const { Universal, Node, MemoryAccount, generateKeyPair, TX_TYPE } = require('@aeternity/aepp-sdk')

// **Note**:
//
Expand Down Expand Up @@ -138,7 +138,7 @@ const NEW_USER_KEYPAIR = generateKeyPair();
{ source: CONTRACT_SOURCE, contractAddress: CONTRACT_ADDRESS }
)
const calldata = contract.calldata.encode('PayingForTxExample', 'set_last_caller', [])
const contractCallTx = await aeSdk.contractCallTx({
const contractCallTx = await aeSdk.buildTx(TX_TYPE.contractCall, {
callerId: await newUserAccount.address(),
contractId: CONTRACT_ADDRESS,
amount: 0,
Expand Down
4 changes: 2 additions & 2 deletions examples/node/paying-for-tx-spend-tx.js
Expand Up @@ -33,7 +33,7 @@
// ## 1. Specify imports
// You need to import `Universal`, `Node` and `MemoryAccount` [Stamps](https://stampit.js.org/essentials/what-is-a-stamp) from the SDK.
// Additionally you import the `generateKeyPair` utility function to generate a new keypair.
const { Universal, Node, MemoryAccount, generateKeyPair } = require('@aeternity/aepp-sdk')
const { Universal, Node, MemoryAccount, generateKeyPair, TX_TYPE } = require('@aeternity/aepp-sdk')

// **Note**:
//
Expand Down Expand Up @@ -95,7 +95,7 @@ const AMOUNT = 1;
// - The balance should now be 1

// ## 7. Create and sign `SpendTx` on behalf of new user
const spendTx = await aeSdk.spendTx({
const spendTx = await aeSdk.buildTx(TX_TYPE.spend, {
senderId: await newUserAccount.address(),
recipientId: await payerAccount.address(),
amount: AMOUNT
Expand Down
12 changes: 6 additions & 6 deletions src/ae/aens.js
Expand Up @@ -29,7 +29,7 @@
import { salt } from '../utils/crypto'
import { commitmentHash, ensureNameValid, isAuctionName } from '../tx/builder/helpers'
import Ae from './'
import { CLIENT_TTL, NAME_TTL } from '../tx/builder/schema'
import { CLIENT_TTL, NAME_TTL, TX_TYPE } from '../tx/builder/schema'
import { ArgumentError } from '../utils/errors'

/**
Expand Down Expand Up @@ -58,7 +58,7 @@ async function revoke (name, options = {}) {
ensureNameValid(name)
const opt = { ...this.Ae.defaults, ...options }

const nameRevokeTx = await this.nameRevokeTx({
const nameRevokeTx = await this.buildTx(TX_TYPE.nameRevoke, {
...opt,
nameId: name,
accountId: await this.address(opt)
Expand Down Expand Up @@ -108,7 +108,7 @@ async function update (name, pointers = {}, options = {}) {
...pointers
}

const nameUpdateTx = await this.nameUpdateTx({
const nameUpdateTx = await this.buildTx(TX_TYPE.nameUpdate, {
...opt,
nameId: name,
accountId: await this.address(opt),
Expand Down Expand Up @@ -146,7 +146,7 @@ async function transfer (name, account, options = {}) {
ensureNameValid(name)
const opt = { ...this.Ae.defaults, ...options }

const nameTransferTx = await this.nameTransferTx({
const nameTransferTx = await this.buildTx(TX_TYPE.nameTransfer, {
...opt,
nameId: name,
accountId: await this.address(opt),
Expand Down Expand Up @@ -237,7 +237,7 @@ async function claim (name, salt, options) {
ensureNameValid(name)
const opt = { ...this.Ae.defaults, ...options }

const claimTx = await this.nameClaimTx({
const claimTx = await this.buildTx(TX_TYPE.nameClaim, {
...opt,
accountId: await this.address(opt),
nameSalt: salt,
Expand Down Expand Up @@ -285,7 +285,7 @@ async function preclaim (name, options = {}) {
const height = await this.height()
const commitmentId = commitmentHash(name, _salt)

const preclaimTx = await this.namePreclaimTx({
const preclaimTx = await this.buildTx(TX_TYPE.namePreClaim, {
...opt,
accountId: await this.address(opt),
commitmentId
Expand Down
12 changes: 8 additions & 4 deletions src/ae/index.js
Expand Up @@ -32,6 +32,7 @@ import BigNumber from 'bignumber.js'
import { AE_AMOUNT_FORMATS } from '../utils/amount-formatter'
import { ArgumentError } from '../utils/errors'
import { mapObject } from '../utils/other'
import { TX_TYPE } from '../tx/builder/schema'

/**
* Sign and post a transaction to the chain
Expand Down Expand Up @@ -74,7 +75,7 @@ async function signUsingGA (tx, { authData, authFun, ...options } = {}) {
async function spend (amount, recipientIdOrName, options) {
const opt = { ...this.Ae.defaults, ...options }
return this.send(
await this.spendTx({
await this.buildTx(TX_TYPE.spend, {
...opt,
senderId: await this.address(opt),
recipientId: await this.resolveName(recipientIdOrName, 'account_pubkey', opt),
Expand Down Expand Up @@ -105,11 +106,14 @@ async function transferFunds (fraction, recipientIdOrName, options) {
const balance = new BigNumber(await this.getBalance(senderId))
const desiredAmount = balance.times(fraction).integerValue(BigNumber.ROUND_HALF_UP)
const { tx: { fee } } = unpackTx(
await this.spendTx({ ...opt, senderId, recipientId, amount: desiredAmount })
await this.buildTx(TX_TYPE.spend, { ...opt, senderId, recipientId, amount: desiredAmount })
)
// Reducing of the amount may reduce transaction fee, so this is not completely accurate
const amount = desiredAmount.plus(fee).gt(balance) ? balance.minus(fee) : desiredAmount
return this.send(await this.spendTx({ ...opt, senderId, recipientId, amount }), opt)
return this.send(
await this.buildTx(TX_TYPE.spend, { ...opt, senderId, recipientId, amount }),
opt
)
}

/**
Expand All @@ -124,7 +128,7 @@ async function transferFunds (fraction, recipientIdOrName, options) {
async function payForTransaction (transaction, options) {
const opt = { ...this.Ae.defaults, ...options }
return this.send(
await this.payingForTx({
await this.buildTx(TX_TYPE.payingFor, {
...opt,
payerId: await this.address(opt),
tx: transaction
Expand Down
14 changes: 7 additions & 7 deletions src/ae/oracle.js
Expand Up @@ -30,7 +30,7 @@ import Ae from './'
import { pause } from '../utils/other'
import { oracleQueryId, decode } from '../tx/builder/helpers'
import { unpackTx } from '../tx/builder'
import { ORACLE_TTL, QUERY_FEE, QUERY_TTL, RESPONSE_TTL } from '../tx/builder/schema'
import { ORACLE_TTL, QUERY_FEE, QUERY_TTL, RESPONSE_TTL, TX_TYPE } from '../tx/builder/schema'
import { RequestTimedOutError } from '../utils/errors'

/**
Expand Down Expand Up @@ -167,7 +167,7 @@ async function registerOracle (queryFormat, responseFormat, options = {}) {
const opt = { ...this.Ae.defaults, ...options } // Preset VmVersion for oracle
const accountId = await this.address(opt)

const oracleRegisterTx = await this.oracleRegisterTx({
const oracleRegisterTx = await this.buildTx(TX_TYPE.oracleRegister, {
...opt,
accountId,
queryFormat,
Expand Down Expand Up @@ -200,15 +200,15 @@ async function postQueryToOracle (oracleId, query, options = {}) {
const opt = { ...this.Ae.defaults, queryFee, ...options }
const senderId = await this.address(opt)

const oracleRegisterTx = await this.oraclePostQueryTx({
const oracleQueryTx = await this.buildTx(TX_TYPE.oracleQuery, {
...opt,
oracleId,
senderId,
query
})
const queryId = oracleQueryId(senderId, unpackTx(oracleRegisterTx).tx.nonce, oracleId)
const queryId = oracleQueryId(senderId, unpackTx(oracleQueryTx).tx.nonce, oracleId)
return {
...await this.send(oracleRegisterTx, opt),
...await this.send(oracleQueryTx, opt),
...await this.getQueryObject(oracleId, queryId)
}
}
Expand All @@ -230,7 +230,7 @@ async function extendOracleTtl (oracleId, oracleTtl, options = {}) {
const opt = { ...this.Ae.defaults, ...options }
const callerId = await this.address(opt)

const oracleExtendTx = await this.oracleExtendTx({
const oracleExtendTx = await this.buildTx(TX_TYPE.oracleExtend, {
...opt,
oracleId,
callerId,
Expand Down Expand Up @@ -261,7 +261,7 @@ async function respondToQuery (oracleId, queryId, response, options = {}) {
const opt = { ...this.Ae.defaults, ...options }
const callerId = await this.address(opt)

const oracleRespondTx = await this.oracleRespondTx({
const oracleRespondTx = await this.buildTx(TX_TYPE.oracleResponse, {
...opt,
oracleId,
queryId,
Expand Down
15 changes: 8 additions & 7 deletions src/contract/aci.js
Expand Up @@ -23,8 +23,9 @@
*/

import { Encoder as Calldata } from '@aeternity/aepp-calldata'
import { DRY_RUN_ACCOUNT, GAS_MAX } from '../tx/builder/schema'
import { DRY_RUN_ACCOUNT, GAS_MAX, TX_TYPE } from '../tx/builder/schema'
import { decode } from '../tx/builder/helpers'
import { buildContractIdByContractTx, unpackTx } from '../tx/builder'
import {
MissingContractDefError,
MissingContractAddressError,
Expand All @@ -43,7 +44,6 @@ import {
AmbiguousEventDefinitionError
} from '../utils/errors'
import { hash } from '../utils/crypto'
import { unpackTx } from '../tx/builder'

/**
* Generate contract ACI object with predefined js methods for contract usage - can be used for
Expand Down Expand Up @@ -185,13 +185,14 @@ export default async function getContractInstance ({
if (instance.deployInfo.address) throw new DuplicateContractError()

const ownerId = await this.address(opt)
const { tx, contractId } = await this.contractCreateTx({
const tx = await this.buildTx(TX_TYPE.contractCreate, {
...opt,
gasLimit: opt.gasLimit ?? await instance._estimateGas('init', params, opt),
callData: instance.calldata.encode(instance._name, 'init', params),
code: instance.bytecode,
ownerId
})
const contractId = buildContractIdByContractTx(tx)
const { hash, rawTx, result, txData } = await sendAndProcess(tx, opt)
instance.deployInfo = Object.freeze({
result,
Expand Down Expand Up @@ -254,15 +255,15 @@ export default async function getContractInstance ({
nonce: opt.nonce ??
(opt.top && (await this.getAccount(callerId, { hash: opt.top })).nonce + 1)
}
const tx = fn === 'init'
? (await this.contractCreateTx({ ...txOpt, code: instance.bytecode, ownerId: callerId })).tx
: await this.contractCallTx({ ...txOpt, callerId, contractId })
const tx = await this.buildTx(...fn === 'init'
? [TX_TYPE.contractCreate, { ...txOpt, code: instance.bytecode, ownerId: callerId }]
: [TX_TYPE.contractCall, { ...txOpt, callerId, contractId }])

const { callObj, ...dryRunOther } = await this.txDryRun(tx, callerId, opt)
await handleCallError(callObj, tx)
res = { ...dryRunOther, tx: unpackTx(tx), result: callObj }
} else {
const tx = await this.contractCallTx({
const tx = await this.buildTx(TX_TYPE.contractCall, {
...opt,
gasLimit: opt.gasLimit ?? await instance._estimateGas(fn, params, opt),
callerId,
Expand Down
5 changes: 3 additions & 2 deletions src/contract/ga/index.js
Expand Up @@ -24,7 +24,7 @@
*/
import Contract from '../../ae/contract'
import { TX_TYPE } from '../../tx/builder/schema'
import { buildTx, unpackTx } from '../../tx/builder'
import { buildContractIdByContractTx, buildTx, unpackTx } from '../../tx/builder'
import { prepareGaParams } from './helpers'
import { hash } from '../../utils/crypto'
import { decode } from '../../utils/encoder'
Expand Down Expand Up @@ -92,14 +92,15 @@ async function createGeneralizedAccount (authFnName, source, args = [], options

const contract = await this.getContractInstance({ source })
await contract.compile()
const { tx, contractId } = await this.gaAttachTx({
const tx = await this.buildTx(TX_TYPE.gaAttach, {
...opt,
gasLimit: opt.gasLimit ?? await contract._estimateGas('init', args, opt),
ownerId,
code: contract.bytecode,
callData: contract.calldata.encode(contract._name, 'init', args),
authFun: hash(authFnName)
})
const contractId = buildContractIdByContractTx(tx)

const { hash: transaction, rawTx } = await this.send(tx, opt)

Expand Down
16 changes: 15 additions & 1 deletion src/tx/builder/index.js
Expand Up @@ -21,12 +21,13 @@ import {
writeId,
writeInt,
buildPointers,
buildContractId,
encode,
decode
} from './helpers'
import { toBytes } from '../../utils/bytes'
import MPTree from '../../utils/mptree'
import { InvalidTxParamsError, SchemaNotFoundError } from '../../utils/errors'
import { ArgumentError, InvalidTxParamsError, SchemaNotFoundError } from '../../utils/errors'

/**
* JavaScript-based Transaction builder
Expand Down Expand Up @@ -442,6 +443,19 @@ export function buildTxHash (rawTx) {
return encode(hash(data), 'th')
}

/**
* Build a contract public key by contractCreateTx or gaAttach
* @param {string} contractTx Transaction
* @return {string} Contract public key
*/
export function buildContractIdByContractTx (contractTx) {
const { txType, tx } = unpackTx(contractTx)
if (![TX_TYPE.contractCreate, TX_TYPE.gaAttach].includes(txType)) {
throw new ArgumentError('contractCreateTx', 'a contractCreateTx or gaAttach', txType)
}
return buildContractId(tx.ownerId, +tx.nonce)
}

export default {
calculateMinFee,
calculateFee,
Expand Down

0 comments on commit 3cf767d

Please sign in to comment.