@aeternity/aepp-sdk 8.2.0 → 10.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +16 -9
  2. package/dist/aepp-sdk.browser-script.js +1 -1
  3. package/dist/aepp-sdk.browser-script.js.LICENSE.txt +0 -9
  4. package/dist/aepp-sdk.browser-script.js.map +1 -1
  5. package/dist/aepp-sdk.browser.js +1 -1
  6. package/dist/aepp-sdk.browser.js.map +1 -1
  7. package/dist/aepp-sdk.js +1 -1
  8. package/dist/aepp-sdk.js.map +1 -1
  9. package/es/account/base.js +33 -119
  10. package/es/account/base.js.map +1 -1
  11. package/es/account/memory.js +17 -19
  12. package/es/account/memory.js.map +1 -1
  13. package/es/account/multiple.js +75 -154
  14. package/es/account/multiple.js.map +1 -1
  15. package/es/ae/aens.js +164 -599
  16. package/es/ae/aens.js.map +1 -1
  17. package/es/ae/contract.js +108 -916
  18. package/es/ae/contract.js.map +1 -1
  19. package/es/ae/index.js +89 -250
  20. package/es/ae/index.js.map +1 -1
  21. package/es/ae/oracle.js +132 -500
  22. package/es/ae/oracle.js.map +1 -1
  23. package/es/chain/index.js +4 -23
  24. package/es/chain/index.js.map +1 -1
  25. package/es/chain/node.js +292 -1018
  26. package/es/chain/node.js.map +1 -1
  27. package/es/channel/handlers.js +597 -1086
  28. package/es/channel/handlers.js.map +1 -1
  29. package/es/channel/index.js +203 -451
  30. package/es/channel/index.js.map +1 -1
  31. package/es/channel/internal.js +129 -301
  32. package/es/channel/internal.js.map +1 -1
  33. package/es/contract/aci/index.js +319 -491
  34. package/es/contract/aci/index.js.map +1 -1
  35. package/es/contract/aci/transformation.js +35 -711
  36. package/es/contract/aci/transformation.js.map +1 -1
  37. package/es/contract/compiler.js +129 -203
  38. package/es/contract/compiler.js.map +1 -1
  39. package/es/contract/ga/helpers.js +17 -122
  40. package/es/contract/ga/helpers.js.map +1 -1
  41. package/es/contract/ga/index.js +102 -247
  42. package/es/contract/ga/index.js.map +1 -1
  43. package/es/contract/index.js +1 -1
  44. package/es/contract/index.js.map +1 -1
  45. package/es/index.js +2 -3
  46. package/es/index.js.map +1 -1
  47. package/es/node-pool/index.js +54 -73
  48. package/es/node-pool/index.js.map +1 -1
  49. package/es/node.js +56 -157
  50. package/es/node.js.map +1 -1
  51. package/es/other.d.ts +1 -1
  52. package/es/tx/builder/helpers.js +49 -89
  53. package/es/tx/builder/helpers.js.map +1 -1
  54. package/es/tx/builder/index.js +205 -303
  55. package/es/tx/builder/index.js.map +1 -1
  56. package/es/tx/builder/schema.js +585 -573
  57. package/es/tx/builder/schema.js.map +1 -1
  58. package/es/tx/index.js +1 -1
  59. package/es/tx/index.js.map +1 -1
  60. package/es/tx/tx-object.js +105 -135
  61. package/es/tx/tx-object.js.map +1 -1
  62. package/es/tx/tx.js +810 -1586
  63. package/es/tx/tx.js.map +1 -1
  64. package/es/tx/validator.js +191 -426
  65. package/es/tx/validator.js.map +1 -1
  66. package/es/utils/aepp-wallet-communication/connection/browser-runtime.js +17 -21
  67. package/es/utils/aepp-wallet-communication/connection/browser-runtime.js.map +1 -1
  68. package/es/utils/aepp-wallet-communication/connection/browser-window-message.js +38 -74
  69. package/es/utils/aepp-wallet-communication/connection/browser-window-message.js.map +1 -1
  70. package/es/utils/aepp-wallet-communication/content-script-bridge.js +14 -15
  71. package/es/utils/aepp-wallet-communication/content-script-bridge.js.map +1 -1
  72. package/es/utils/aepp-wallet-communication/helpers.js +60 -105
  73. package/es/utils/aepp-wallet-communication/helpers.js.map +1 -1
  74. package/es/utils/aepp-wallet-communication/rpc/aepp-rpc.js +179 -510
  75. package/es/utils/aepp-wallet-communication/rpc/aepp-rpc.js.map +1 -1
  76. package/es/utils/aepp-wallet-communication/rpc/rpc-client.js +70 -89
  77. package/es/utils/aepp-wallet-communication/rpc/rpc-client.js.map +1 -1
  78. package/es/utils/aepp-wallet-communication/rpc/wallet-rpc.js +354 -603
  79. package/es/utils/aepp-wallet-communication/rpc/wallet-rpc.js.map +1 -1
  80. package/es/utils/aepp-wallet-communication/schema.js +43 -39
  81. package/es/utils/aepp-wallet-communication/schema.js.map +1 -1
  82. package/es/utils/aepp-wallet-communication/wallet-detector.js +32 -58
  83. package/es/utils/aepp-wallet-communication/wallet-detector.js.map +1 -1
  84. package/es/utils/amount-formatter.js +41 -61
  85. package/es/utils/amount-formatter.js.map +1 -1
  86. package/es/utils/async-init.js +28 -64
  87. package/es/utils/async-init.js.map +1 -1
  88. package/es/utils/bignumber.js +3 -11
  89. package/es/utils/bignumber.js.map +1 -1
  90. package/es/utils/bytes.js +5 -9
  91. package/es/utils/bytes.js.map +1 -1
  92. package/es/utils/crypto.js +49 -75
  93. package/es/utils/crypto.js.map +1 -1
  94. package/es/utils/hd-wallet.js +45 -81
  95. package/es/utils/hd-wallet.js.map +1 -1
  96. package/es/utils/json-big.js +16 -49
  97. package/es/utils/json-big.js.map +1 -1
  98. package/es/utils/keystore.js +81 -246
  99. package/es/utils/keystore.js.map +1 -1
  100. package/es/utils/mptree.js +88 -134
  101. package/es/utils/mptree.js.map +1 -1
  102. package/es/utils/other.js +10 -60
  103. package/es/utils/other.js.map +1 -1
  104. package/es/utils/semver-satisfies.js +9 -28
  105. package/es/utils/semver-satisfies.js.map +1 -1
  106. package/es/utils/string.js +4 -13
  107. package/es/utils/string.js.map +1 -1
  108. package/es/utils/swagger.js +85 -218
  109. package/es/utils/swagger.js.map +1 -1
  110. package/package.json +52 -43
  111. package/src/account/base.js +8 -9
  112. package/src/account/multiple.js +20 -16
  113. package/src/ae/aens.js +25 -21
  114. package/src/ae/contract.js +65 -246
  115. package/src/ae/index.js +31 -7
  116. package/src/ae/oracle.js +21 -17
  117. package/src/chain/index.js +2 -12
  118. package/src/chain/node.js +26 -29
  119. package/src/channel/handlers.js +0 -1
  120. package/src/channel/index.js +4 -5
  121. package/src/contract/aci/index.js +221 -106
  122. package/src/contract/aci/transformation.js +30 -422
  123. package/src/contract/compiler.js +45 -4
  124. package/src/contract/ga/helpers.js +2 -12
  125. package/src/contract/ga/index.js +22 -26
  126. package/src/index.js +2 -4
  127. package/src/node-pool/index.js +21 -12
  128. package/src/node.js +22 -26
  129. package/src/tx/builder/helpers.js +12 -24
  130. package/src/tx/builder/index.js +18 -15
  131. package/src/tx/builder/schema.js +43 -108
  132. package/src/tx/tx-object.js +0 -2
  133. package/src/tx/tx.js +157 -144
  134. package/src/tx/validator.js +134 -202
  135. package/src/utils/aepp-wallet-communication/rpc/aepp-rpc.js +1 -3
  136. package/src/utils/aepp-wallet-communication/rpc/wallet-rpc.js +9 -10
  137. package/src/utils/aepp-wallet-communication/schema.js +1 -3
  138. package/src/utils/amount-formatter.ts +1 -1
  139. package/src/utils/bignumber.ts +2 -1
  140. package/src/utils/crypto.js +4 -17
  141. package/src/utils/other.ts +1 -1
  142. package/src/utils/semver-satisfies.ts +1 -1
  143. package/src/utils/swagger.js +24 -7
  144. package/CHANGELOG.md +0 -1716
  145. package/src/contract/aci/helpers.js +0 -140
@@ -1,229 +1,161 @@
1
- import {
2
- verify,
3
- decodeBase58Check,
4
- assertedType
5
- } from '../utils/crypto'
6
- import { encode } from '../tx/builder/helpers'
1
+ import { verify, hash } from '../utils/crypto'
2
+ import { encode, decode } from './builder/helpers'
7
3
 
8
4
  import BigNumber from 'bignumber.js'
9
- import {
10
- BASE_VERIFICATION_SCHEMA,
11
- CONTRACT_VERIFICATION_SCHEMA,
12
- MIN_GAS_PRICE,
13
- NAME_CLAIM_VERIFICATION_SCHEMA,
14
- OBJECT_ID_TX_TYPE,
15
- OBJECT_TAG_SIGNED_TRANSACTION,
16
- PROTOCOL_VM_ABI,
17
- SIGNATURE_VERIFICATION_SCHEMA,
18
- TX_TYPE
19
- } from './builder/schema'
20
- import { buildTxHash, calculateFee, unpackTx } from './builder'
21
- import NodePool from '../node-pool'
5
+ import { MIN_GAS_PRICE, PROTOCOL_VM_ABI, TX_TYPE } from './builder/schema'
6
+ import { calculateFee, unpackTx } from './builder'
22
7
 
23
8
  /**
24
9
  * Transaction validator
25
10
  * @module @aeternity/aepp-sdk/es/tx/validator
26
- * @export TransactionValidator
27
- * @example import { TransactionValidator } from '@aeternity/aepp-sdk'
11
+ * @export verifyTransaction
12
+ * @example import { verifyTransaction } from '@aeternity/aepp-sdk'
28
13
  */
29
14
 
30
- const VALIDATORS = {
31
- // VALIDATE SIGNATURE
32
- signature ({ rlpEncoded, signature, ownerPublicKey, networkId = 'ae_mainnet' }) {
33
- const txWithNetworkId = Buffer.concat([Buffer.from(networkId), rlpEncoded])
34
- const txHashWithNetworkId = Buffer.concat([Buffer.from(networkId), buildTxHash(rlpEncoded, { raw: true })])
35
- const decodedPub = decodeBase58Check(assertedType(ownerPublicKey, 'ak'))
36
- return verify(txWithNetworkId, signature, decodedPub) || verify(txHashWithNetworkId, signature, decodedPub)
15
+ const validators = [
16
+ async ({ encodedTx, signatures }, { account, node, parentTxTypes }) => {
17
+ if ((encodedTx ?? signatures) === undefined) return []
18
+ if (signatures.length !== 1) return [] // TODO: Support multisignature?
19
+ const prefix = Buffer.from([
20
+ node.nodeNetworkId,
21
+ ...parentTxTypes.includes(TX_TYPE.payingFor) ? ['inner_tx'] : []
22
+ ].join('-'))
23
+ const txWithNetworkId = Buffer.concat([prefix, encodedTx.rlpEncoded])
24
+ const txHashWithNetworkId = Buffer.concat([prefix, hash(encodedTx.rlpEncoded)])
25
+ const decodedPub = decode(account.id, 'ak')
26
+ if (verify(txWithNetworkId, signatures[0], decodedPub) ||
27
+ verify(txHashWithNetworkId, signatures[0], decodedPub)) return []
28
+ return [{
29
+ message: 'Signature cannot be verified, please ensure that you transaction have' +
30
+ ' the correct prefix and the correct private key for the sender address',
31
+ key: 'InvalidSignature',
32
+ checkedKeys: ['encodedTx', 'signatures']
33
+ }]
37
34
  },
38
- // VALIDATE IF ENOUGH FEE
39
- insufficientFee ({ minFee, fee }) {
40
- return BigNumber(minFee).lte(BigNumber(fee))
35
+ async ({ encodedTx, tx }, { node, parentTxTypes, txType }) => {
36
+ if ((encodedTx ?? tx) === undefined) return []
37
+ return verifyTransaction(
38
+ encode((encodedTx ?? tx).rlpEncoded, 'tx'),
39
+ node,
40
+ [...parentTxTypes, txType]
41
+ )
41
42
  },
42
- // VALIDATE IF TTL VALID
43
- expiredTTL ({ ttl, height }) {
44
- return BigNumber(ttl).eq(0) || BigNumber(ttl).gte(BigNumber(height))
45
- },
46
- // Insufficient Balance for Amount plus Fee
47
- insufficientBalanceForAmountFee ({ balance, amount = 0, fee }) {
48
- return BigNumber(balance).gte(BigNumber(amount).plus(fee))
43
+ (tx, { txType }) => {
44
+ if (tx.fee === undefined) return []
45
+ const minFee = calculateFee(0, txType, {
46
+ gas: +tx.gas || 0, params: tx, showWarning: false, vsn: tx.VSN
47
+ })
48
+ if (new BigNumber(minFee).lte(tx.fee)) return []
49
+ return [{
50
+ message: `Fee ${tx.fee} is too low, minimum fee for this transaction is ${minFee}`,
51
+ key: 'InsufficientFee',
52
+ checkedKeys: ['fee']
53
+ }]
49
54
  },
50
- // Insufficient Balance for Amount
51
- insufficientBalanceForAmount ({ balance, amount = 0 }) {
52
- return BigNumber(balance).gte(BigNumber(amount))
55
+ ({ ttl }, { height }) => {
56
+ if (ttl === undefined) return []
57
+ ttl = +ttl
58
+ if (ttl === 0 || ttl >= height) return []
59
+ return [{
60
+ message: `TTL ${ttl} is already expired, current height is ${height}`,
61
+ key: 'ExpiredTTL',
62
+ checkedKeys: ['ttl']
63
+ }]
53
64
  },
54
- // IF NONCE USED
55
- nonceUsed ({ accountNonce, nonce }) {
56
- return BigNumber(nonce).gt(BigNumber(accountNonce))
65
+ ({ amount, fee, nameFee, tx }, { account, parentTxTypes, txType }) => {
66
+ if ((amount ?? fee ?? nameFee) === undefined) return []
67
+ const cost = new BigNumber(fee).plus(nameFee || 0).plus(amount || 0)
68
+ .plus(txType === TX_TYPE.payingFor ? tx.tx.encodedTx.tx.fee : 0)
69
+ .minus(parentTxTypes.includes(TX_TYPE.payingFor) ? fee : 0)
70
+ if (cost.lte(account.balance)) return []
71
+ return [{
72
+ message: `Account balance ${account.balance} is not enough to execute the transaction that costs ${cost.toFixed()}`,
73
+ key: 'InsufficientBalance',
74
+ checkedKeys: ['amount', 'fee', 'nameFee']
75
+ }]
57
76
  },
58
- // IF NONCE TO HIGH
59
- nonceHigh ({ accountNonce, nonce }) {
60
- return !(BigNumber(nonce).gt(BigNumber(accountNonce).plus(1)))
77
+ ({ nonce }, { account, parentTxTypes }) => {
78
+ if (nonce === undefined || parentTxTypes.includes(TX_TYPE.gaMeta)) return []
79
+ nonce = +nonce
80
+ const validNonce = account.nonce + 1
81
+ if (nonce === validNonce) return []
82
+ return [{
83
+ ...nonce < validNonce
84
+ ? {
85
+ message: `Nonce ${nonce} is already used, valid nonce is ${validNonce}`,
86
+ key: 'NonceAlreadyUsed'
87
+ }
88
+ : {
89
+ message: `Nonce ${nonce} is too high, valid nonce is ${validNonce}`,
90
+ key: 'NonceHigh'
91
+ },
92
+ checkedKeys: ['nonce']
93
+ }]
61
94
  },
62
- minGasPrice ({ gasPrice }) {
63
- return isNaN(gasPrice) || BigNumber(gasPrice).gte(BigNumber(MIN_GAS_PRICE))
95
+ ({ gasPrice }) => {
96
+ if (gasPrice === undefined) return []
97
+ if (gasPrice >= MIN_GAS_PRICE) return []
98
+ return [{
99
+ message: `Gas price ${gasPrice} must be bigger then ${MIN_GAS_PRICE}`,
100
+ key: 'MinGasPrice',
101
+ checkedKeys: ['gasPrice']
102
+ }]
64
103
  },
65
- // VM/ABI version validation based on consensus protocol version
66
- vmAndAbiVersion ({ ctVersion, abiVersion, consensusProtocolVersion, txType }) {
67
- // If not contract tx
104
+ ({ ctVersion, abiVersion }, { txType, node }) => {
105
+ const { consensusProtocolVersion } = node.getNodeInfo()
106
+ const protocol = PROTOCOL_VM_ABI[consensusProtocolVersion]
107
+ if (!protocol) throw new Error(`Unsupported protocol: ${consensusProtocolVersion}`)
108
+ // If not contract create tx
68
109
  if (!ctVersion) ctVersion = { abiVersion }
69
- const supportedProtocol = PROTOCOL_VM_ABI[consensusProtocolVersion]
70
- // If protocol not implemented
71
- if (!supportedProtocol) return true
72
- // If protocol for tx type not implemented
73
- const txProtocol = supportedProtocol[txType]
74
-
75
- return !Object.entries(ctVersion)
76
- .reduce((acc, [key, value]) =>
77
- [...acc, value === undefined ? true : txProtocol[key].includes(parseInt(value))],
78
- []).includes(false)
79
- },
80
- insufficientBalanceForFeeNameFee ({ nameFee, fee, balance, VSN }) {
81
- return VSN === 1 || BigNumber(balance).gte(BigNumber(nameFee).plus(fee))
82
- }
83
- }
84
-
85
- const resolveDataForBase = async (chain, { ownerPublicKey }) => {
86
- let accountNonce = 0
87
- let accountBalance = 0
88
- try {
89
- const { nonce, balance } = await chain.api.getAccountByPubkey(ownerPublicKey)
90
- accountNonce = nonce
91
- accountBalance = balance
92
- } catch (e) { console.log('We can not get info about this publicKey') }
93
- return {
94
- height: (await chain.api.getCurrentKeyBlockHeight()).height,
95
- balance: accountBalance,
96
- accountNonce,
97
- ownerPublicKey,
98
- ...chain.getNodeInfo()
99
- }
100
- }
101
-
102
- // Verification using SCHEMA
103
- const verifySchema = (schema, data) => {
104
- // Verify through schema
105
- return schema.reduce(
106
- (acc, [msg, validatorKey, { key, type, txKey }]) => {
107
- if (!VALIDATORS[validatorKey](data)) acc.push({ msg: msg(data), txKey, type })
108
- return acc
109
- },
110
- []
111
- )
112
- }
113
-
114
- /**
115
- * Unpack and verify transaction (verify nonce, ttl, fee, signature, account balance)
116
- * @function
117
- * @alias module:@aeternity/aepp-sdk/es/tx/validator
118
- *
119
- * @param {String} txHash Base64Check transaction hash
120
- * @param {Object} [options={}] Options
121
- * @param {String} [options.networkId] networkId Use in signature verification
122
- * @return {Promise<Object>} Object with verification errors and warnings
123
- */
124
- async function unpackAndVerify (txHash, { networkId } = {}) {
125
- const { tx: unpackedTx, rlpEncoded, txType } = unpackTx(txHash)
126
-
127
- if (+unpackedTx.tag === OBJECT_TAG_SIGNED_TRANSACTION) {
128
- const { txType, tx } = unpackedTx.encodedTx
129
- const signatures = unpackedTx.signatures.map(raw => ({ raw, hash: encode(raw, 'sg') }))
130
- const rlpEncodedTx = unpackedTx.encodedTx.rlpEncoded
131
-
132
- return {
133
- validation: await this.verifyTx({ tx, signatures, rlpEncoded: rlpEncodedTx }, networkId),
134
- tx,
135
- signatures,
136
- txType
110
+ const txProtocol = protocol[txType]
111
+ if (!txProtocol) return []
112
+ if (Object.entries(ctVersion).some(([key, value]) => !txProtocol[key].includes(+value))) {
113
+ return [{
114
+ message: `ABI/VM version ${JSON.stringify(ctVersion)} is wrong, supported is: ${JSON.stringify(txProtocol)}`,
115
+ key: 'VmAndAbiVersionMismatch',
116
+ checkedKeys: ['ctVersion', 'abiVersion']
117
+ }]
137
118
  }
119
+ return []
138
120
  }
139
- return {
140
- validation: await this.verifyTx({ tx: unpackedTx, rlpEncoded }, networkId),
141
- tx: unpackedTx,
142
- txType
143
- }
144
- }
121
+ ]
145
122
 
146
- const getOwnerPublicKey = (tx) =>
147
- tx[['senderId', 'accountId', 'ownerId', 'callerId', 'oracleId', 'fromId', 'initiator', 'gaId'].find(key => tx[key])].replace('ok_', 'ak_')
123
+ const getSenderAddress = tx => [
124
+ 'senderId', 'accountId', 'ownerId', 'callerId',
125
+ 'oracleId', 'fromId', 'initiator', 'gaId', 'payerId'
126
+ ]
127
+ .map(key => tx[key])
128
+ .filter(a => a)
129
+ .map(a => a.replace(/^ok_/, 'ak_'))[0]
148
130
 
149
131
  /**
150
- * Verify transaction (verify nonce, ttl, fee, signature, account balance)
132
+ * Transaction Validator
133
+ * This function validates some of transaction properties,
134
+ * to make sure it can be posted it to the chain
151
135
  * @function
152
136
  * @alias module:@aeternity/aepp-sdk/es/tx/validator
153
- *
154
- * @param {Object} [data={}] data TX data object
155
- * @param {String} [data.tx] tx Transaction hash
156
- * @param {Array} [data.signatures] signatures Transaction signature's
157
- * @param {Array} [data.rlpEncoded] rlpEncoded RLP encoded transaction
158
- * @param {String} networkId networkId Use in signature verification
159
- * @return {Promise<Array>} Object with verification errors and warnings
137
+ * @rtype (tx: String, node) => void
138
+ * @param {String} transaction Base64Check-encoded transaction
139
+ * @param {Object} node Node to validate transaction against
140
+ * @param {String[]} [parentTxTypes] Types of parent transactions
141
+ * @return {Promise<Object[]>} Array with verification errors
142
+ * @example const errors = await verifyTransaction(transaction, node)
160
143
  */
161
- async function verifyTx ({ tx, signatures, rlpEncoded }, networkId) {
162
- networkId = networkId || this.getNetworkId() || 'ae_mainnet'
163
- // Fetch data for verification
164
- const ownerPublicKey = getOwnerPublicKey(tx)
165
- const gas = Object.prototype.hasOwnProperty.call(tx, 'gas') ? +tx.gas : 0
166
- const txType = OBJECT_ID_TX_TYPE[+tx.tag]
167
- const resolvedData = {
168
- minFee: calculateFee(0, txType, { gas, params: tx, showWarning: false, vsn: tx.VSN }),
169
- ...(await resolveDataForBase(this, { ownerPublicKey })),
170
- ...tx,
171
- txType
172
- }
173
- const signatureVerification = signatures && signatures.length
174
- ? verifySchema(SIGNATURE_VERIFICATION_SCHEMA, {
175
- rlpEncoded,
176
- signature: signatures[0].raw,
177
- ownerPublicKey,
178
- networkId
179
- })
180
- : []
181
- const baseVerification = verifySchema(BASE_VERIFICATION_SCHEMA, resolvedData)
144
+ export default async function verifyTransaction (transaction, node, parentTxTypes = []) {
145
+ const { tx, txType } = unpackTx(transaction)
182
146
 
183
- return [
184
- ...baseVerification,
185
- ...signatureVerification,
186
- ...customVerification(txType, resolvedData)
187
- ]
188
- }
147
+ const address = getSenderAddress(tx) ??
148
+ (txType === TX_TYPE.signed ? getSenderAddress(tx.encodedTx.tx) : null)
149
+ const [account, height] = await Promise.all([
150
+ address && node.api.getAccountByPubkey(address).catch(() => ({
151
+ id: address,
152
+ balance: new BigNumber(0),
153
+ nonce: 0
154
+ })),
155
+ node.api.getCurrentKeyBlockHeight().then(({ height }) => height)
156
+ ])
189
157
 
190
- /**
191
- * Verification for speciific txType
192
- * @param txType
193
- * @param data
194
- * @return {Array}
195
- */
196
- function customVerification (txType, data) {
197
- switch (txType) {
198
- case TX_TYPE.contractCreate:
199
- case TX_TYPE.contractCall:
200
- case TX_TYPE.oracleRegister:
201
- return verifySchema(CONTRACT_VERIFICATION_SCHEMA, data)
202
- case TX_TYPE.nameClaim:
203
- return verifySchema(NAME_CLAIM_VERIFICATION_SCHEMA, data)
204
- default:
205
- return []
206
- }
158
+ return (await Promise.all(
159
+ validators.map(v => v(tx, { txType, node, account, height, parentTxTypes })))
160
+ ).flat()
207
161
  }
208
-
209
- /**
210
- * Transaction Validator Stamp
211
- * This stamp give us possibility to unpack and validate some of transaction properties,
212
- * to make sure we can post it to the chain
213
- * @function
214
- * @alias module:@aeternity/aepp-sdk/es/tx/validator
215
- * @rtype Stamp
216
- * @param {Object} [options={}] - Initializer object
217
- * @param {Object} [options.url] - Node url
218
- * @param {Object} [options.internalUrl] - Node internal url
219
- * @return {Object} Transaction Validator instance
220
- * @example TransactionValidator({url: 'https://testnet.aeternity.io'})
221
- */
222
- const TransactionValidator = NodePool.compose({
223
- methods: {
224
- verifyTx,
225
- unpackAndVerify
226
- }
227
- })
228
-
229
- export default TransactionValidator
@@ -5,9 +5,7 @@
5
5
  * @export AeppRpc
6
6
  * @example import ContentScriptBridge from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/aepp-rpc'
7
7
  */
8
- import * as R from 'ramda'
9
8
  import { v4 as uuid } from 'uuid'
10
-
11
9
  import Ae from '../../../ae'
12
10
  import RpcClient from './rpc-client'
13
11
  import { getHandler, message, voidFn } from '../helpers'
@@ -236,7 +234,7 @@ export default Ae.compose({
236
234
  if (!this.rpcClient || !this.rpcClient.isConnected()) throw new Error('You are not connected to Wallet')
237
235
  if (!this.rpcClient.currentAccount) throw new Error('You are not subscribed for an account.')
238
236
  if (options.onAccount && !this.rpcClient.hasAccessToAccount(options.onAccount)) throw new Error(`You do not have access to account ${options.onAccount}`)
239
- const opt = R.merge(this.Ae.defaults, options)
237
+ const opt = { ...this.Ae.defaults, ...options }
240
238
  if (!opt.walletBroadcast) {
241
239
  const signed = await this.signTransaction(tx, { onAccount: opt.onAccount })
242
240
  return this.sendTransaction(signed, opt)
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import { v4 as uuid } from 'uuid'
9
9
  import Ae from '../../../ae'
10
+ import verifyTransaction from '../../../tx/validator'
10
11
  import AccountMultiple from '../../../account/multiple'
11
12
  import TxObject from '../../../tx/tx-object'
12
13
  import RpcClient from './rpc-client'
@@ -73,7 +74,7 @@ const REQUESTS = {
73
74
  }
74
75
  }
75
76
  } catch (e) {
76
- console.error(e)
77
+ if (instance.debug) console.error(e)
77
78
  return { error: ERRORS.internalError({ msg: e.message }) }
78
79
  }
79
80
  },
@@ -111,22 +112,20 @@ const REQUESTS = {
111
112
  try {
112
113
  onAcc = resolveOnAccount(instance.addresses(), address, opt)
113
114
  } catch (e) {
114
- console.error(e)
115
+ if (instance.debug) console.error(e)
115
116
  return { error: ERRORS.internalError({ msg: e.message }) }
116
117
  }
117
118
  try {
118
119
  return {
119
- result: {
120
- ...returnSigned
121
- ? { signedTransaction: await instance.signTransaction(rawTx || tx, { onAccount: onAcc }) }
122
- : { transactionHash: await instance.send(rawTx || tx, { onAccount: onAcc, verify: false }) }
123
- }
120
+ result: returnSigned
121
+ ? { signedTransaction: await instance.signTransaction(rawTx || tx, { onAccount: onAcc }) }
122
+ : { transactionHash: await instance.send(rawTx || tx, { onAccount: onAcc, verify: false }) }
124
123
  }
125
124
  } catch (e) {
126
125
  if (!returnSigned) {
127
126
  // Validate transaction
128
- const validationResult = await instance.unpackAndVerify(rawTx || tx)
129
- if (validationResult.validation.length) return { error: ERRORS.invalidTransaction(validationResult) }
127
+ const validation = await verifyTransaction(rawTx || tx, instance.selectedNode.instance)
128
+ if (validation.length) return { error: ERRORS.invalidTransaction(validation) }
130
129
  // Send broadcast failed error to aepp
131
130
  return { error: ERRORS.broadcastFailed(e.message) }
132
131
  }
@@ -157,7 +156,7 @@ const REQUESTS = {
157
156
  }
158
157
  }
159
158
  } catch (e) {
160
- console.error(e)
159
+ if (instance.debug) console.error(e)
161
160
  return { error: ERRORS.internalError({ msg: e.message }) }
162
161
  }
163
162
  },
@@ -1,6 +1,4 @@
1
- import * as R from 'ramda'
2
-
3
- const asEnum = (array) => R.zipObj(array, array)
1
+ const asEnum = (array) => Object.fromEntries(array.map(a => [a, a]))
4
2
 
5
3
  export const VERSION = 1
6
4
 
@@ -88,7 +88,7 @@ export const formatAmount = (
88
88
  const denominations = Object.values(AE_AMOUNT_FORMATS)
89
89
  if (!denominations.includes(denomination)) throw new Error(`Invalid denomination: ${denomination}`)
90
90
  if (!denominations.includes(targetDenomination)) throw new Error(`Invalid target denomination: ${targetDenomination}`)
91
- if (!isBigNumber(value)) throw new Error(`Value ${value.toString()} is not type of number`)
91
+ if (!isBigNumber(value)) throw new Error(`Value ${value?.toString()} is not type of number`)
92
92
 
93
93
  return new BigNumber(value)
94
94
  .shiftedBy(DENOMINATION_MAGNITUDE[denomination] - DENOMINATION_MAGNITUDE[targetDenomination])
@@ -19,7 +19,8 @@ export const parseBigNumber = (number: string | number | BigNumber): string =>
19
19
  * @return {Boolean}
20
20
  */
21
21
  export const isBigNumber = (number: string | number | BigNumber): boolean =>
22
- !isNaN(number as number) || Number.isInteger(number) || BigNumber.isBigNumber(number)
22
+ ['number', 'object', 'string', 'bigint'].includes(typeof number) &&
23
+ (!isNaN(number as number) || Number.isInteger(number) || BigNumber.isBigNumber(number))
23
24
 
24
25
  /**
25
26
  * BigNumber ceil operation
@@ -28,6 +28,7 @@ import aesjs from 'aes-js'
28
28
  import shajs from 'sha.js'
29
29
 
30
30
  import { str2buf, toBytes } from './bytes'
31
+ import { decode } from '../tx/builder/helpers'
31
32
  import { hash } from './crypto-ts'
32
33
 
33
34
  export * from './crypto-ts'
@@ -56,7 +57,7 @@ export function getAddressFromPriv (secret) {
56
57
  export function isAddressValid (address, prefix = 'ak') {
57
58
  if (typeof address !== 'string') return false
58
59
  try {
59
- return decodeBase58Check(assertedType(address, prefix)).length === 32
60
+ return decode(address, prefix).length === 32
60
61
  } catch (e) {
61
62
  return false
62
63
  }
@@ -173,7 +174,7 @@ export function encodeUnsigned (value) {
173
174
  * @return {String} - Contract address
174
175
  */
175
176
  export function encodeContractAddress (owner, nonce) {
176
- const publicKey = decodeBase58Check(assertedType(owner, 'ak'))
177
+ const publicKey = decode(owner, 'ak')
177
178
  const binary = Buffer.concat([publicKey, encodeUnsigned(nonce)])
178
179
  return `ct_${encodeBase58Check(hash(binary))}`
179
180
  }
@@ -296,20 +297,6 @@ export function aeEncodeKey (binaryKey) {
296
297
  return `ak_${pubKeyAddress}`
297
298
  }
298
299
 
299
- /**
300
- * Assert encoded type and return its payload
301
- * @rtype (data: String, type: String) => String, throws: Error
302
- * @param {String} data - ae data
303
- * @param {String} type - Prefix
304
- * @param {Boolean} omitError - Return false instead of throwing the error if data doesn't match expected type
305
- * @return {String|Boolean} Payload
306
- */
307
- export function assertedType (data, type, omitError) {
308
- if (RegExp(`^${type}_.+$`).test(data)) return data.split('_')[1]
309
- else if (omitError) return false
310
- else throw new Error(`Data doesn't match expected type ${type}`)
311
- }
312
-
313
300
  /**
314
301
  * Check key pair for validity
315
302
  *
@@ -336,7 +323,7 @@ export function isValidKeypair (privateKey, publicKey) {
336
323
  */
337
324
  export function encryptData (msg, publicKey) {
338
325
  const ephemeralKeyPair = nacl.box.keyPair()
339
- const pubKeyUInt8Array = decodeBase58Check(assertedType(publicKey, 'ak'))
326
+ const pubKeyUInt8Array = decode(publicKey, 'ak')
340
327
  const nonce = nacl.randomBytes(nacl.box.nonceLength)
341
328
 
342
329
  const encryptedMessage = nacl.box(
@@ -1,6 +1,6 @@
1
1
  import { snakeToPascal, pascalToSnake } from './string'
2
2
 
3
- export const pause = async (duration: number): Promise<undefined> =>
3
+ export const pause = async (duration: number): Promise<void> =>
4
4
  await new Promise(resolve => setTimeout(resolve, duration))
5
5
 
6
6
  export const mapObject = (
@@ -1,6 +1,6 @@
1
1
  export default function (version: string, geVersion: string, ltVersion: string): boolean {
2
2
  const getComponents = (v: string): number[] => v
3
- .split('-')[0].split('.').map(i => +i)
3
+ .split(/[-+]/)[0].split('.').map(i => +i)
4
4
 
5
5
  const versionComponents = getComponents(version)
6
6
  const geComponents = getComponents(geVersion)
@@ -39,13 +39,27 @@ let warnedAboutInternalApiUsage = false
39
39
  * @param {String} [options.internalUrl] - Node internal URL
40
40
  * @param {Boolean} [options.disableBigNumbers]
41
41
  * @param {Boolean} [options.disableCaseConversion]
42
+ * @param {Function} [options.responseInterceptor]
42
43
  * @return {Object} Swagger client
43
44
  * @example (await genSwaggerClient('https://mainnet.aeternity.io/api')).getAccountByPubkey('ak_jupBUgZNbcC4krDLR3tAkw1iBZoBbkNeShAq4atBtpFWmz36r')
44
45
  */
45
- export default async (specUrl, { spec, internalUrl, disableBigNumbers, disableCaseConversion } = {}) => {
46
+ export default async (
47
+ specUrl,
48
+ { spec, internalUrl, disableBigNumbers, disableCaseConversion, responseInterceptor } = {}
49
+ ) => {
46
50
  spec = spec || await (await fetch(specUrl)).json()
47
51
  const jsonImp = disableBigNumbers ? JSON : JsonBig
48
52
 
53
+ if (
54
+ [
55
+ 'https://compiler.aepps.com',
56
+ 'https://latest.compiler.aepps.com'
57
+ ].includes(new URL(specUrl).origin) ||
58
+ new URL(specUrl).origin.includes('https://')
59
+ ) {
60
+ spec.schemes = ['https']
61
+ }
62
+
49
63
  const [external, internal] = await Promise.all([specUrl, internalUrl].map((url) => {
50
64
  if (!url) return null
51
65
  return SwaggerClient({
@@ -54,9 +68,10 @@ export default async (specUrl, { spec, internalUrl, disableBigNumbers, disableCa
54
68
  responseInterceptor: response => {
55
69
  if (!response.text) return response
56
70
  const body = jsonImp.parse(response.text)
57
- return Object.assign(response, {
71
+ Object.assign(response, {
58
72
  body: disableCaseConversion ? body : pascalizeKeys(body)
59
73
  })
74
+ return (responseInterceptor && responseInterceptor(response)) || response
60
75
  }
61
76
  })
62
77
  }))
@@ -87,11 +102,13 @@ export default async (specUrl, { spec, internalUrl, disableBigNumbers, disableCa
87
102
  const opSpec = opSpecs[opId]
88
103
  const parameters = [
89
104
  ...opSpec.parameters,
90
- ...opSpec.requestBody ? [{
91
- required: opSpec.requestBody.required,
92
- schema: Object.values(opSpec.requestBody.content)[0].schema,
93
- name: '__requestBody'
94
- }] : []
105
+ ...opSpec.requestBody
106
+ ? [{
107
+ required: opSpec.requestBody.required,
108
+ schema: Object.values(opSpec.requestBody.content)[0].schema,
109
+ name: '__requestBody'
110
+ }]
111
+ : []
95
112
  ]
96
113
  const required = parameters.filter(param => param.required).map(p => p.name)
97
114
  if (args.length < required.length) throw new Error('swagger: Not enough arguments')