@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.
- package/CHANGELOG.md +216 -337
- package/README.md +16 -9
- package/dist/aepp-sdk.browser-script.js +1 -1
- package/dist/aepp-sdk.browser-script.js.LICENSE.txt +0 -9
- package/dist/aepp-sdk.browser-script.js.map +1 -1
- package/dist/aepp-sdk.browser.js +1 -1
- package/dist/aepp-sdk.browser.js.map +1 -1
- package/dist/aepp-sdk.js +1 -1
- package/dist/aepp-sdk.js.map +1 -1
- package/es/account/base.js +36 -120
- package/es/account/base.js.map +1 -1
- package/es/account/memory.js +17 -19
- package/es/account/memory.js.map +1 -1
- package/es/account/multiple.js +79 -156
- package/es/account/multiple.js.map +1 -1
- package/es/ae/aens.js +205 -626
- package/es/ae/aens.js.map +1 -1
- package/es/ae/contract.js +114 -918
- package/es/ae/contract.js.map +1 -1
- package/es/ae/index.js +90 -250
- package/es/ae/index.js.map +1 -1
- package/es/ae/oracle.js +136 -504
- package/es/ae/oracle.js.map +1 -1
- package/es/ae/universal.js.map +1 -1
- package/es/chain/index.js +12 -27
- package/es/chain/index.js.map +1 -1
- package/es/chain/node.js +289 -1020
- package/es/chain/node.js.map +1 -1
- package/es/channel/handlers.js +597 -1086
- package/es/channel/handlers.js.map +1 -1
- package/es/channel/index.js +238 -465
- package/es/channel/index.js.map +1 -1
- package/es/channel/internal.js +129 -301
- package/es/channel/internal.js.map +1 -1
- package/es/contract/aci/index.js +328 -495
- package/es/contract/aci/index.js.map +1 -1
- package/es/contract/aci/transformation.js +35 -711
- package/es/contract/aci/transformation.js.map +1 -1
- package/es/contract/compiler.js +131 -203
- package/es/contract/compiler.js.map +1 -1
- package/es/contract/ga/helpers.js +17 -122
- package/es/contract/ga/helpers.js.map +1 -1
- package/es/contract/ga/index.js +108 -249
- package/es/contract/ga/index.js.map +1 -1
- package/es/contract/index.js +7 -3
- package/es/contract/index.js.map +1 -1
- package/es/index.js +3 -3
- package/es/index.js.map +1 -1
- package/es/node-pool/index.js +57 -74
- package/es/node-pool/index.js.map +1 -1
- package/es/node.js +65 -161
- package/es/node.js.map +1 -1
- package/es/other.d.ts +1 -1
- package/es/tx/builder/helpers.js +62 -115
- package/es/tx/builder/helpers.js.map +1 -1
- package/es/tx/builder/index.js +218 -309
- package/es/tx/builder/index.js.map +1 -1
- package/es/tx/builder/schema.js +586 -573
- package/es/tx/builder/schema.js.map +1 -1
- package/es/tx/index.js +102 -13
- package/es/tx/index.js.map +1 -1
- package/es/tx/tx-object.js +114 -138
- package/es/tx/tx-object.js.map +1 -1
- package/es/tx/tx.js +810 -1586
- package/es/tx/tx.js.map +1 -1
- package/es/tx/validator.js +191 -426
- package/es/tx/validator.js.map +1 -1
- package/es/utils/aepp-wallet-communication/connection/browser-runtime.js +20 -23
- package/es/utils/aepp-wallet-communication/connection/browser-runtime.js.map +1 -1
- package/es/utils/aepp-wallet-communication/connection/browser-window-message.js +53 -80
- package/es/utils/aepp-wallet-communication/connection/browser-window-message.js.map +1 -1
- package/es/utils/aepp-wallet-communication/connection/index.js +2 -1
- package/es/utils/aepp-wallet-communication/connection/index.js.map +1 -1
- package/es/utils/aepp-wallet-communication/content-script-bridge.js +24 -19
- package/es/utils/aepp-wallet-communication/content-script-bridge.js.map +1 -1
- package/es/utils/aepp-wallet-communication/helpers.js +60 -105
- package/es/utils/aepp-wallet-communication/helpers.js.map +1 -1
- package/es/utils/aepp-wallet-communication/rpc/aepp-rpc.js +191 -514
- package/es/utils/aepp-wallet-communication/rpc/aepp-rpc.js.map +1 -1
- package/es/utils/aepp-wallet-communication/rpc/rpc-client.js +78 -93
- package/es/utils/aepp-wallet-communication/rpc/rpc-client.js.map +1 -1
- package/es/utils/aepp-wallet-communication/rpc/wallet-rpc.js +381 -613
- package/es/utils/aepp-wallet-communication/rpc/wallet-rpc.js.map +1 -1
- package/es/utils/aepp-wallet-communication/schema.js +43 -39
- package/es/utils/aepp-wallet-communication/schema.js.map +1 -1
- package/es/utils/aepp-wallet-communication/wallet-detector.js +32 -58
- package/es/utils/aepp-wallet-communication/wallet-detector.js.map +1 -1
- package/es/utils/amount-formatter.js +41 -61
- package/es/utils/amount-formatter.js.map +1 -1
- package/es/utils/async-init.js +28 -64
- package/es/utils/async-init.js.map +1 -1
- package/es/utils/bignumber.js +3 -11
- package/es/utils/bignumber.js.map +1 -1
- package/es/utils/bytes.js +5 -9
- package/es/utils/bytes.js.map +1 -1
- package/es/utils/crypto.js +41 -106
- package/es/utils/crypto.js.map +1 -1
- package/es/utils/hd-wallet.js +45 -81
- package/es/utils/hd-wallet.js.map +1 -1
- package/es/utils/json-big.js +16 -49
- package/es/utils/json-big.js.map +1 -1
- package/es/utils/keystore.js +81 -246
- package/es/utils/keystore.js.map +1 -1
- package/es/utils/mptree.js +88 -134
- package/es/utils/mptree.js.map +1 -1
- package/es/utils/other.js +10 -60
- package/es/utils/other.js.map +1 -1
- package/es/utils/semver-satisfies.js +9 -28
- package/es/utils/semver-satisfies.js.map +1 -1
- package/es/utils/string.js +4 -13
- package/es/utils/string.js.map +1 -1
- package/es/utils/swagger.js +87 -224
- package/es/utils/swagger.js.map +1 -1
- package/package.json +51 -44
- package/src/account/base.js +11 -10
- package/src/account/multiple.js +24 -18
- package/src/ae/aens.js +64 -61
- package/src/ae/contract.js +71 -248
- package/src/ae/index.js +34 -9
- package/src/ae/oracle.js +30 -22
- package/src/ae/universal.js +3 -1
- package/src/chain/index.js +10 -16
- package/src/chain/node.js +38 -38
- package/src/channel/handlers.js +10 -4
- package/src/channel/index.js +44 -20
- package/src/contract/aci/index.js +234 -112
- package/src/contract/aci/transformation.js +30 -422
- package/src/contract/compiler.js +50 -5
- package/src/contract/ga/helpers.js +6 -14
- package/src/contract/ga/index.js +28 -28
- package/src/contract/index.js +6 -2
- package/src/index.js +4 -4
- package/src/node-pool/index.js +24 -13
- package/src/node.js +29 -30
- package/src/tx/builder/helpers.js +31 -56
- package/src/tx/builder/index.js +67 -28
- package/src/tx/builder/schema.js +79 -121
- package/src/tx/index.js +101 -12
- package/src/tx/tx-object.js +25 -8
- package/src/tx/tx.js +229 -150
- package/src/tx/validator.js +134 -202
- package/src/utils/aepp-wallet-communication/connection/browser-runtime.js +3 -2
- package/src/utils/aepp-wallet-communication/connection/browser-window-message.js +25 -7
- package/src/utils/aepp-wallet-communication/connection/index.js +2 -1
- package/src/utils/aepp-wallet-communication/content-script-bridge.js +10 -4
- package/src/utils/aepp-wallet-communication/helpers.js +4 -2
- package/src/utils/aepp-wallet-communication/rpc/aepp-rpc.js +33 -12
- package/src/utils/aepp-wallet-communication/rpc/rpc-client.js +9 -5
- package/src/utils/aepp-wallet-communication/rpc/wallet-rpc.js +59 -29
- package/src/utils/aepp-wallet-communication/schema.js +1 -3
- package/src/utils/aepp-wallet-communication/wallet-detector.js +4 -1
- package/src/utils/amount-formatter.ts +1 -1
- package/src/utils/bignumber.ts +2 -1
- package/src/utils/crypto.js +4 -68
- package/src/utils/keystore.js +10 -2
- package/src/utils/other.ts +1 -1
- package/src/utils/semver-satisfies.ts +1 -1
- package/src/utils/swagger.js +22 -10
- package/src/contract/aci/helpers.js +0 -140
package/src/tx/validator.js
CHANGED
|
@@ -1,229 +1,161 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
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
|
-
|
|
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
|
|
27
|
-
* @example import {
|
|
11
|
+
* @export verifyTransaction
|
|
12
|
+
* @example import { verifyTransaction } from '@aeternity/aepp-sdk'
|
|
28
13
|
*/
|
|
29
14
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
return
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
63
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
|
70
|
-
|
|
71
|
-
if (!
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
|
|
140
|
-
validation: await this.verifyTx({ tx: unpackedTx, rlpEncoded }, networkId),
|
|
141
|
-
tx: unpackedTx,
|
|
142
|
-
txType
|
|
143
|
-
}
|
|
144
|
-
}
|
|
121
|
+
]
|
|
145
122
|
|
|
146
|
-
const
|
|
147
|
-
|
|
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
|
-
*
|
|
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 {
|
|
155
|
-
* @param {
|
|
156
|
-
* @param {
|
|
157
|
-
* @
|
|
158
|
-
* @
|
|
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
|
|
162
|
-
|
|
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
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
-
|
|
192
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 {
|
|
119
|
-
*
|
|
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 ({
|
|
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
|
|
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
|
|
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
|
|
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
|
|
66
|
-
* @
|
|
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 } = {}) =>
|
|
54
|
+
export const responseMessage = (id, method, { error, result } = {}) =>
|
|
55
|
+
({ id, method, ...(error ? { error } : { result }) })
|
|
55
56
|
|
|
56
|
-
export const sendResponseMessage = (client) => (id, method, data) =>
|
|
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
|
|
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
|
-
|
|
46
|
-
|
|
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(
|
|
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 ({
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
152
|
-
* @param {
|
|
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
|
|
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
|
}
|