@aeternity/aepp-sdk 8.2.1 → 10.0.0

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 (159) hide show
  1. package/CHANGELOG.md +216 -337
  2. package/README.md +16 -9
  3. package/dist/aepp-sdk.browser-script.js +1 -1
  4. package/dist/aepp-sdk.browser-script.js.LICENSE.txt +0 -9
  5. package/dist/aepp-sdk.browser-script.js.map +1 -1
  6. package/dist/aepp-sdk.browser.js +1 -1
  7. package/dist/aepp-sdk.browser.js.map +1 -1
  8. package/dist/aepp-sdk.js +1 -1
  9. package/dist/aepp-sdk.js.map +1 -1
  10. package/es/account/base.js +36 -120
  11. package/es/account/base.js.map +1 -1
  12. package/es/account/memory.js +17 -19
  13. package/es/account/memory.js.map +1 -1
  14. package/es/account/multiple.js +79 -156
  15. package/es/account/multiple.js.map +1 -1
  16. package/es/ae/aens.js +205 -626
  17. package/es/ae/aens.js.map +1 -1
  18. package/es/ae/contract.js +114 -918
  19. package/es/ae/contract.js.map +1 -1
  20. package/es/ae/index.js +90 -250
  21. package/es/ae/index.js.map +1 -1
  22. package/es/ae/oracle.js +136 -504
  23. package/es/ae/oracle.js.map +1 -1
  24. package/es/ae/universal.js.map +1 -1
  25. package/es/chain/index.js +12 -27
  26. package/es/chain/index.js.map +1 -1
  27. package/es/chain/node.js +289 -1020
  28. package/es/chain/node.js.map +1 -1
  29. package/es/channel/handlers.js +597 -1086
  30. package/es/channel/handlers.js.map +1 -1
  31. package/es/channel/index.js +238 -465
  32. package/es/channel/index.js.map +1 -1
  33. package/es/channel/internal.js +129 -301
  34. package/es/channel/internal.js.map +1 -1
  35. package/es/contract/aci/index.js +328 -495
  36. package/es/contract/aci/index.js.map +1 -1
  37. package/es/contract/aci/transformation.js +35 -711
  38. package/es/contract/aci/transformation.js.map +1 -1
  39. package/es/contract/compiler.js +131 -203
  40. package/es/contract/compiler.js.map +1 -1
  41. package/es/contract/ga/helpers.js +17 -122
  42. package/es/contract/ga/helpers.js.map +1 -1
  43. package/es/contract/ga/index.js +108 -249
  44. package/es/contract/ga/index.js.map +1 -1
  45. package/es/contract/index.js +7 -3
  46. package/es/contract/index.js.map +1 -1
  47. package/es/index.js +3 -3
  48. package/es/index.js.map +1 -1
  49. package/es/node-pool/index.js +57 -74
  50. package/es/node-pool/index.js.map +1 -1
  51. package/es/node.js +65 -161
  52. package/es/node.js.map +1 -1
  53. package/es/other.d.ts +1 -1
  54. package/es/tx/builder/helpers.js +62 -115
  55. package/es/tx/builder/helpers.js.map +1 -1
  56. package/es/tx/builder/index.js +218 -309
  57. package/es/tx/builder/index.js.map +1 -1
  58. package/es/tx/builder/schema.js +586 -573
  59. package/es/tx/builder/schema.js.map +1 -1
  60. package/es/tx/index.js +102 -13
  61. package/es/tx/index.js.map +1 -1
  62. package/es/tx/tx-object.js +114 -138
  63. package/es/tx/tx-object.js.map +1 -1
  64. package/es/tx/tx.js +810 -1586
  65. package/es/tx/tx.js.map +1 -1
  66. package/es/tx/validator.js +191 -426
  67. package/es/tx/validator.js.map +1 -1
  68. package/es/utils/aepp-wallet-communication/connection/browser-runtime.js +20 -23
  69. package/es/utils/aepp-wallet-communication/connection/browser-runtime.js.map +1 -1
  70. package/es/utils/aepp-wallet-communication/connection/browser-window-message.js +53 -80
  71. package/es/utils/aepp-wallet-communication/connection/browser-window-message.js.map +1 -1
  72. package/es/utils/aepp-wallet-communication/connection/index.js +2 -1
  73. package/es/utils/aepp-wallet-communication/connection/index.js.map +1 -1
  74. package/es/utils/aepp-wallet-communication/content-script-bridge.js +24 -19
  75. package/es/utils/aepp-wallet-communication/content-script-bridge.js.map +1 -1
  76. package/es/utils/aepp-wallet-communication/helpers.js +60 -105
  77. package/es/utils/aepp-wallet-communication/helpers.js.map +1 -1
  78. package/es/utils/aepp-wallet-communication/rpc/aepp-rpc.js +191 -514
  79. package/es/utils/aepp-wallet-communication/rpc/aepp-rpc.js.map +1 -1
  80. package/es/utils/aepp-wallet-communication/rpc/rpc-client.js +78 -93
  81. package/es/utils/aepp-wallet-communication/rpc/rpc-client.js.map +1 -1
  82. package/es/utils/aepp-wallet-communication/rpc/wallet-rpc.js +381 -613
  83. package/es/utils/aepp-wallet-communication/rpc/wallet-rpc.js.map +1 -1
  84. package/es/utils/aepp-wallet-communication/schema.js +43 -39
  85. package/es/utils/aepp-wallet-communication/schema.js.map +1 -1
  86. package/es/utils/aepp-wallet-communication/wallet-detector.js +32 -58
  87. package/es/utils/aepp-wallet-communication/wallet-detector.js.map +1 -1
  88. package/es/utils/amount-formatter.js +41 -61
  89. package/es/utils/amount-formatter.js.map +1 -1
  90. package/es/utils/async-init.js +28 -64
  91. package/es/utils/async-init.js.map +1 -1
  92. package/es/utils/bignumber.js +3 -11
  93. package/es/utils/bignumber.js.map +1 -1
  94. package/es/utils/bytes.js +5 -9
  95. package/es/utils/bytes.js.map +1 -1
  96. package/es/utils/crypto.js +41 -106
  97. package/es/utils/crypto.js.map +1 -1
  98. package/es/utils/hd-wallet.js +45 -81
  99. package/es/utils/hd-wallet.js.map +1 -1
  100. package/es/utils/json-big.js +16 -49
  101. package/es/utils/json-big.js.map +1 -1
  102. package/es/utils/keystore.js +81 -246
  103. package/es/utils/keystore.js.map +1 -1
  104. package/es/utils/mptree.js +88 -134
  105. package/es/utils/mptree.js.map +1 -1
  106. package/es/utils/other.js +10 -60
  107. package/es/utils/other.js.map +1 -1
  108. package/es/utils/semver-satisfies.js +9 -28
  109. package/es/utils/semver-satisfies.js.map +1 -1
  110. package/es/utils/string.js +4 -13
  111. package/es/utils/string.js.map +1 -1
  112. package/es/utils/swagger.js +87 -224
  113. package/es/utils/swagger.js.map +1 -1
  114. package/package.json +51 -44
  115. package/src/account/base.js +11 -10
  116. package/src/account/multiple.js +24 -18
  117. package/src/ae/aens.js +64 -61
  118. package/src/ae/contract.js +71 -248
  119. package/src/ae/index.js +34 -9
  120. package/src/ae/oracle.js +30 -22
  121. package/src/ae/universal.js +3 -1
  122. package/src/chain/index.js +10 -16
  123. package/src/chain/node.js +38 -38
  124. package/src/channel/handlers.js +10 -4
  125. package/src/channel/index.js +44 -20
  126. package/src/contract/aci/index.js +234 -112
  127. package/src/contract/aci/transformation.js +30 -422
  128. package/src/contract/compiler.js +50 -5
  129. package/src/contract/ga/helpers.js +6 -14
  130. package/src/contract/ga/index.js +28 -28
  131. package/src/contract/index.js +6 -2
  132. package/src/index.js +4 -4
  133. package/src/node-pool/index.js +24 -13
  134. package/src/node.js +29 -30
  135. package/src/tx/builder/helpers.js +31 -56
  136. package/src/tx/builder/index.js +67 -28
  137. package/src/tx/builder/schema.js +79 -121
  138. package/src/tx/index.js +101 -12
  139. package/src/tx/tx-object.js +25 -8
  140. package/src/tx/tx.js +229 -150
  141. package/src/tx/validator.js +134 -202
  142. package/src/utils/aepp-wallet-communication/connection/browser-runtime.js +3 -2
  143. package/src/utils/aepp-wallet-communication/connection/browser-window-message.js +25 -7
  144. package/src/utils/aepp-wallet-communication/connection/index.js +2 -1
  145. package/src/utils/aepp-wallet-communication/content-script-bridge.js +10 -4
  146. package/src/utils/aepp-wallet-communication/helpers.js +4 -2
  147. package/src/utils/aepp-wallet-communication/rpc/aepp-rpc.js +33 -12
  148. package/src/utils/aepp-wallet-communication/rpc/rpc-client.js +9 -5
  149. package/src/utils/aepp-wallet-communication/rpc/wallet-rpc.js +59 -29
  150. package/src/utils/aepp-wallet-communication/schema.js +1 -3
  151. package/src/utils/aepp-wallet-communication/wallet-detector.js +4 -1
  152. package/src/utils/amount-formatter.ts +1 -1
  153. package/src/utils/bignumber.ts +2 -1
  154. package/src/utils/crypto.js +4 -68
  155. package/src/utils/keystore.js +10 -2
  156. package/src/utils/other.ts +1 -1
  157. package/src/utils/semver-satisfies.ts +1 -1
  158. package/src/utils/swagger.js +22 -10
  159. 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
@@ -18,10 +18,11 @@
18
18
  /**
19
19
  * Browser runtime connector module
20
20
  *
21
- * This is the complement to {@link module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection}.
21
+ * This is the complement to
22
+ * {@link module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection}.
22
23
  * @module @aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/browser-runtime
23
24
  * @export BrowserRuntimeConnection
24
- * @example import BrowserRuntimeConnection from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/browser-runtime'
25
+ * @example import { BrowserRuntimeConnection } from '@aeternity/aepp-sdk'
25
26
  */
26
27
  import stampit from '@stamp/it'
27
28
 
@@ -18,10 +18,13 @@
18
18
  /**
19
19
  * Browser window Post Message connector module
20
20
  *
21
- * This is the complement to {@link module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection}.
21
+ * This is the complement to
22
+ * {@link module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection}.
22
23
  * @module @aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/browser-window-message
23
24
  * @export BrowserWindowMessageConnection
24
- * @example import BrowserWindowMessageConnection from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/browser-window-message'
25
+ * @example
26
+ * import BrowserWindowMessageConnection
27
+ * from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/browser-window-message'
25
28
  */
26
29
  import stampit from '@stamp/it'
27
30
  import WalletConnection from '.'
@@ -102,27 +105,42 @@ const getTarget = () => {
102
105
  const isContentScript = isExtensionContext && isWeb
103
106
  if (isContentScript) return window
104
107
  // When we is the main page we need to decide the target by our self
105
- // Probably can be implemented some algo for checking DOM for Iframes and somehow decide which Iframe to talk
108
+ // Probably can be implemented some algo for checking DOM for Iframes and somehow decide which
109
+ // Iframe to talk
106
110
  return isInIframe() ? window.parent : undefined
107
111
  }
108
112
 
109
113
  /**
110
114
  * BrowserWindowMessageConnection
111
115
  * @function
112
- * @alias module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/browser-window-message
116
+ * @alias module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication\
117
+ * /connection/browser-window-message
113
118
  * @rtype Stamp
114
119
  * @param {Object} [params={}] - Initializer object
115
120
  * @param {Object} [params.target=window.parent] - Target window for message
116
121
  * @param {Object} [params.self=window] - Host window for message
117
122
  * @param {Object} [params.origin] - Origin of receiver
118
- * @param {Object} [params.sendDirection] - Optional field for wrapping messages in additional structure({ type: 'to_aepp' || 'to_waellet', data }).Used for handling messages netween content script and page
119
- * @param {Object} [params.receiveDirection='to_aepp'] - Optional(default: 'to_aepp') field for unwrapping messages from additional structure({ type: 'to_aepp' || 'to_waellet', data }).Used for handling messages netween content script and page
123
+ * @param {String} [params.sendDirection] Wrapping messages into additional struct
124
+ * ({ type: 'to_aepp' || 'to_waellet', data })
125
+ * Used for handling messages between content script and page
126
+ * @param {String} [params.receiveDirection='to_aepp'] Unwrapping messages from additional struct
127
+ * ({ type: 'to_aepp' || 'to_waellet', data })
128
+ * Used for handling messages between content script and page
120
129
  * @param {Object} [params.connectionInfo={}] - Connection info object
121
130
  * @param {Boolean} [params.debug=false] - Debug flag
122
131
  * @return {Object}
123
132
  */
124
133
  export default stampit({
125
- init ({ connectionInfo = {}, target = getTarget(), self = window, origin, sendDirection, receiveDirection = MESSAGE_DIRECTION.to_aepp, debug = false, forceOrigin = false } = {}) {
134
+ init ({
135
+ connectionInfo = {},
136
+ target = getTarget(),
137
+ self = window,
138
+ origin,
139
+ sendDirection,
140
+ receiveDirection = MESSAGE_DIRECTION.to_aepp,
141
+ debug = false,
142
+ forceOrigin = false
143
+ } = {}) {
126
144
  if (sendDirection && !Object.keys(MESSAGE_DIRECTION).includes(sendDirection)) throw new Error(`sendDirection must be one of [${Object.keys(MESSAGE_DIRECTION)}]`)
127
145
  if (!Object.keys(MESSAGE_DIRECTION).includes(receiveDirection)) throw new Error(`receiveDirection must be one of [${Object.keys(MESSAGE_DIRECTION)}]`)
128
146
  this.connectionInfo = { id: uuid(), ...connectionInfo }
@@ -19,7 +19,8 @@
19
19
  * Wallet Connection base module
20
20
  * @module @aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection
21
21
  * @export WalletConnection
22
- * @example import WalletConnection from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection'
22
+ * @example
23
+ * import WalletConnection from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection'
23
24
  */
24
25
 
25
26
  import { required } from '@stamp/required'
@@ -20,7 +20,9 @@
20
20
  *
21
21
  * @module @aeternity/aepp-sdk/es/utils/aepp-wallet-communication/content-script-bridge
22
22
  * @export ContentScriptBridge
23
- * @example import ContentScriptBridge from '@aeternity/aepp-sdk/es/utils/wallet-communication/content-script-bridge
23
+ * @example
24
+ * import ContentScriptBridge
25
+ * from '@aeternity/aepp-sdk/es/utils/wallet-communication/content-script-bridge
24
26
  */
25
27
  import stampit from '@stamp/it'
26
28
 
@@ -56,14 +58,18 @@ function stop () {
56
58
 
57
59
  /**
58
60
  * ContentScriptBridge stamp
59
- * Provide functionality to easly redirect messages from page to extension and from extension to page through content script
61
+ * Provide functionality to easly redirect messages from page to extension and from extension to
62
+ * page through content script
60
63
  * Using Runtime(Extension) and WindowPostMessage(Web-Page) connections
61
64
  * @function
62
65
  * @alias module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/content-script-bridge
63
66
  * @rtype Stamp
64
67
  * @param {Object} params - Initializer object
65
- * @param {Object} params.pageConnection - Page connection object(@link module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/browser-window-message)
66
- * @param {Object} params.extConnection - Extension connection object(module: @aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/browser-runtime)
68
+ * @param {Object} params.pageConnection - Page connection object
69
+ * (@link module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/\
70
+ * browser-window-message)
71
+ * @param {Object} params.extConnection - Extension connection object
72
+ * (@link module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/browser-runtime)
67
73
  * @return {Object}
68
74
  */
69
75
  export default stampit({
@@ -51,9 +51,11 @@ export const getHandler = (schema, msg, { debug = false } = {}) => {
51
51
 
52
52
  export const message = (method, params = {}) => ({ method, params })
53
53
 
54
- export const responseMessage = (id, method, { error, result } = {}) => ({ id, method, ...(error ? { error } : { result }) })
54
+ export const responseMessage = (id, method, { error, result } = {}) =>
55
+ ({ id, method, ...(error ? { error } : { result }) })
55
56
 
56
- export const sendResponseMessage = (client) => (id, method, data) => client.sendMessage(responseMessage(id, method, data), true)
57
+ export const sendResponseMessage = (client) => (id, method, data) =>
58
+ client.sendMessage(responseMessage(id, method, data), true)
57
59
 
58
60
  export const voidFn = () => undefined
59
61
 
@@ -3,11 +3,11 @@
3
3
  *
4
4
  * @module @aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/aepp-rpc
5
5
  * @export AeppRpc
6
- * @example import ContentScriptBridge from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/aepp-rpc'
6
+ * @example
7
+ * import ContentScriptBridge
8
+ * from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/aepp-rpc'
7
9
  */
8
- import * as R from 'ramda'
9
10
  import { v4 as uuid } from 'uuid'
10
-
11
11
  import Ae from '../../../ae'
12
12
  import RpcClient from './rpc-client'
13
13
  import { getHandler, message, voidFn } from '../helpers'
@@ -42,15 +42,21 @@ const RESPONSES = {
42
42
  [METHODS.aepp.subscribeAddress]: (instance) =>
43
43
  (msg) => {
44
44
  if (msg.result) {
45
- msg.result.address && (instance.rpcClient.accounts = msg.result.address)
46
- msg.result.subscription && (instance.rpcClient.addressSubscription = msg.result.subscription)
45
+ if (msg.result.address) {
46
+ instance.rpcClient.accounts = msg.result.address
47
+ }
48
+ if (msg.result.subscription) {
49
+ instance.rpcClient.addressSubscription = msg.result.subscription
50
+ }
47
51
  }
48
52
 
49
53
  instance.rpcClient.processResponse(msg, ({ id, result }) => [result])
50
54
  },
51
55
  [METHODS.aepp.sign]: (instance) =>
52
56
  (msg) => {
53
- instance.rpcClient.processResponse(msg, ({ id, result }) => [result.signedTransaction || result.transactionHash])
57
+ instance.rpcClient.processResponse(
58
+ msg, ({ id, result }) => [result.signedTransaction || result.transactionHash]
59
+ )
54
60
  },
55
61
  [METHODS.aepp.signMessage]: (instance) =>
56
62
  (msg) => {
@@ -84,7 +90,15 @@ const handleMessage = (instance) => async (msg) => {
84
90
  * @return {Object}
85
91
  */
86
92
  export default Ae.compose({
87
- async init ({ name, onAddressChange = voidFn, onDisconnect = voidFn, onNetworkChange = voidFn, connection, forceValidation = false, debug = false }) {
93
+ async init ({
94
+ name,
95
+ onAddressChange = voidFn,
96
+ onDisconnect = voidFn,
97
+ onNetworkChange = voidFn,
98
+ connection,
99
+ forceValidation = false,
100
+ debug = false
101
+ }) {
88
102
  const eventsHandlers = ['onDisconnect', 'onAddressChange', 'onNetworkChange']
89
103
  this.connection = connection
90
104
  this.name = name
@@ -168,7 +182,7 @@ export default Ae.compose({
168
182
  * @function subscribeAddress
169
183
  * @instance
170
184
  * @rtype (type: String, value: String) => Promise
171
- * @param {String} type Type of subscription can be one of ['current'(just for selected account updates), 'connected(all accounts)']
185
+ * @param {String} type Should be one of 'current' (the selected account), 'connected' (all)
172
186
  * @param {String} value Subscription action('subscribe'|'unsubscribe')
173
187
  * @return {Promise} Address from wallet
174
188
  */
@@ -188,7 +202,10 @@ export default Ae.compose({
188
202
  if (!this.rpcClient || !this.rpcClient.isConnected()) throw new Error('You are not connected to Wallet')
189
203
  if (!this.rpcClient.currentAccount) throw new Error('You are not subscribed for an account.')
190
204
  if (opt.onAccount && !this.rpcClient.hasAccessToAccount(opt.onAccount)) throw new Error(`You do not have access to account ${opt.onAccount}`)
191
- return this.rpcClient.request(METHODS.aepp.sign, { ...opt, tx, returnSigned: true, networkId: this.getNetworkId() })
205
+ return this.rpcClient.request(
206
+ METHODS.aepp.sign,
207
+ { ...opt, tx, returnSigned: true, networkId: this.getNetworkId() }
208
+ )
192
209
  },
193
210
  /**
194
211
  * Overwriting of `signMessage` AE method
@@ -223,7 +240,8 @@ export default Ae.compose({
223
240
  /**
224
241
  * Overwriting of `send` AE method
225
242
  * All sdk API which use it will be send notification to wallet and wait for callBack
226
- * This method will sign, broadcast and wait until transaction will be accepted using rpc communication with wallet
243
+ * This method will sign, broadcast and wait until transaction will be accepted using rpc
244
+ * communication with wallet
227
245
  * @function send
228
246
  * @instance
229
247
  * @rtype (tx: String, options = {}) => Promise
@@ -236,12 +254,15 @@ export default Ae.compose({
236
254
  if (!this.rpcClient || !this.rpcClient.isConnected()) throw new Error('You are not connected to Wallet')
237
255
  if (!this.rpcClient.currentAccount) throw new Error('You are not subscribed for an account.')
238
256
  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)
257
+ const opt = { ...this.Ae.defaults, ...options }
240
258
  if (!opt.walletBroadcast) {
241
259
  const signed = await this.signTransaction(tx, { onAccount: opt.onAccount })
242
260
  return this.sendTransaction(signed, opt)
243
261
  }
244
- return this.rpcClient.request(METHODS.aepp.sign, { onAccount: opt.onAccount, tx, returnSigned: false, networkId: this.getNetworkId() })
262
+ return this.rpcClient.request(
263
+ METHODS.aepp.sign,
264
+ { onAccount: opt.onAccount, tx, returnSigned: false, networkId: this.getNetworkId() }
265
+ )
245
266
  }
246
267
  }
247
268
  })
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * @module @aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/rpc-client
5
5
  * @export { RpcClient, RpcClients }
6
- * @example import RpcClient from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/rpc-client'
6
+ * @example
7
+ * import RpcClient from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/rpc-client'
7
8
  */
8
9
  import stampit from '@stamp/it'
9
10
 
@@ -18,7 +19,9 @@ import { sendMessage, message, isValidAccounts } from '../helpers'
18
19
  * @param {Object} param Init params object
19
20
  * @param {String} param.name Client name
20
21
  * @param {Object} param.connection Connection object
21
- * @param {Function[]} param.handlers Arrays with two function for handling messages ([ onMessage: Function, onDisconnect: Function])
22
+ * @param {Function[]} param.handlers Array with two function for message handling
23
+ * @param {Function} param.handlers[0] Message handler
24
+ * @param {Function} param.handlers[1] Disconnect callback
22
25
  * @return {Object}
23
26
  */
24
27
  export default stampit({
@@ -148,10 +151,11 @@ export default stampit({
148
151
  },
149
152
  /**
150
153
  * Update accounts and sent `update.address` notification to AEPP
151
- * @param {{ current: Object, connected: Object }} accounts Object with current and connected accounts
152
- * @param {{ forceNotification: Boolean }} [options={ forceNotification: false }] Don not sent update notification to AEPP
154
+ * @param {{ current: Object, connected: Object }} accounts Current and connected accounts
155
+ * @param {Object} [options]
156
+ * @param {Boolean} [options.forceNotification] Don't sent update notification to AEPP
153
157
  */
154
- setAccounts (accounts, { forceNotification = false } = {}) {
158
+ setAccounts (accounts, { forceNotification } = {}) {
155
159
  if (!isValidAccounts(accounts)) {
156
160
  throw new Error('Invalid accounts object. Should be object like: `{ connected: {}, selected: {} }`')
157
161
  }