@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
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module @aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/wallet-rpc
|
|
5
5
|
* @export WalletRpc
|
|
6
|
-
* @example
|
|
6
|
+
* @example
|
|
7
|
+
* import WalletRpc from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/wallet-rpc'
|
|
7
8
|
*/
|
|
8
9
|
import { v4 as uuid } from 'uuid'
|
|
9
10
|
import Ae from '../../../ae'
|
|
11
|
+
import verifyTransaction from '../../../tx/validator'
|
|
10
12
|
import AccountMultiple from '../../../account/multiple'
|
|
11
13
|
import TxObject from '../../../tx/tx-object'
|
|
12
14
|
import RpcClient from './rpc-client'
|
|
@@ -73,7 +75,7 @@ const REQUESTS = {
|
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
77
|
} catch (e) {
|
|
76
|
-
console.error(e)
|
|
78
|
+
if (instance.debug) console.error(e)
|
|
77
79
|
return { error: ERRORS.internalError({ msg: e.message }) }
|
|
78
80
|
}
|
|
79
81
|
},
|
|
@@ -88,20 +90,28 @@ const REQUESTS = {
|
|
|
88
90
|
return callInstance(
|
|
89
91
|
'onAskAccounts',
|
|
90
92
|
{},
|
|
91
|
-
({ accounts } = {}) => ({
|
|
93
|
+
({ accounts } = {}) => ({
|
|
94
|
+
result: accounts ||
|
|
95
|
+
[...Object.keys(client.accounts.current), ...Object.keys(client.accounts.connected)]
|
|
96
|
+
}),
|
|
92
97
|
(error) => ({ error: ERRORS.rejectedByUser(error) })
|
|
93
98
|
)
|
|
94
99
|
},
|
|
95
|
-
[METHODS.aepp.sign] (callInstance, instance, client,
|
|
100
|
+
[METHODS.aepp.sign] (callInstance, instance, client, options) {
|
|
101
|
+
const { tx, onAccount, networkId, returnSigned = false } = options
|
|
96
102
|
const address = onAccount || client.currentAccount
|
|
97
103
|
// Update client with new networkId
|
|
98
104
|
networkId && client.updateInfo({ networkId })
|
|
99
105
|
// Authorization check
|
|
100
106
|
if (!client.isConnected()) return { error: ERRORS.notAuthorize() }
|
|
101
107
|
// Account permission check
|
|
102
|
-
if (!client.hasAccessToAccount(address))
|
|
108
|
+
if (!client.hasAccessToAccount(address)) {
|
|
109
|
+
return { error: ERRORS.permissionDeny({ account: address }) }
|
|
110
|
+
}
|
|
103
111
|
// NetworkId check
|
|
104
|
-
if (!networkId || networkId !== instance.getNetworkId())
|
|
112
|
+
if (!networkId || networkId !== instance.getNetworkId()) {
|
|
113
|
+
return { error: ERRORS.unsupportedNetwork() }
|
|
114
|
+
}
|
|
105
115
|
|
|
106
116
|
return callInstance(
|
|
107
117
|
'onSign',
|
|
@@ -111,22 +121,20 @@ const REQUESTS = {
|
|
|
111
121
|
try {
|
|
112
122
|
onAcc = resolveOnAccount(instance.addresses(), address, opt)
|
|
113
123
|
} catch (e) {
|
|
114
|
-
console.error(e)
|
|
124
|
+
if (instance.debug) console.error(e)
|
|
115
125
|
return { error: ERRORS.internalError({ msg: e.message }) }
|
|
116
126
|
}
|
|
117
127
|
try {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
}
|
|
128
|
+
const t = rawTx || tx
|
|
129
|
+
const result = returnSigned
|
|
130
|
+
? { signedTransaction: await instance.signTransaction(t, { onAccount: onAcc }) }
|
|
131
|
+
: { transactionHash: await instance.send(t, { onAccount: onAcc, verify: false }) }
|
|
132
|
+
return { result }
|
|
125
133
|
} catch (e) {
|
|
126
134
|
if (!returnSigned) {
|
|
127
135
|
// Validate transaction
|
|
128
|
-
const
|
|
129
|
-
if (
|
|
136
|
+
const validation = await verifyTransaction(rawTx || tx, instance.selectedNode.instance)
|
|
137
|
+
if (validation.length) return { error: ERRORS.invalidTransaction(validation) }
|
|
130
138
|
// Send broadcast failed error to aepp
|
|
131
139
|
return { error: ERRORS.broadcastFailed(e.message) }
|
|
132
140
|
}
|
|
@@ -140,7 +148,9 @@ const REQUESTS = {
|
|
|
140
148
|
// Authorization check
|
|
141
149
|
if (!client.isConnected()) return { error: ERRORS.notAuthorize() }
|
|
142
150
|
const address = onAccount || client.currentAccount
|
|
143
|
-
if (!client.hasAccessToAccount(address))
|
|
151
|
+
if (!client.hasAccessToAccount(address)) {
|
|
152
|
+
return { error: ERRORS.permissionDeny({ account: address }) }
|
|
153
|
+
}
|
|
144
154
|
|
|
145
155
|
return callInstance(
|
|
146
156
|
'onMessageSign',
|
|
@@ -157,7 +167,7 @@ const REQUESTS = {
|
|
|
157
167
|
}
|
|
158
168
|
}
|
|
159
169
|
} catch (e) {
|
|
160
|
-
console.error(e)
|
|
170
|
+
if (instance.debug) console.error(e)
|
|
161
171
|
return { error: ERRORS.internalError({ msg: e.message }) }
|
|
162
172
|
}
|
|
163
173
|
},
|
|
@@ -169,7 +179,9 @@ const REQUESTS = {
|
|
|
169
179
|
const handleMessage = (instance, id) => async (msg, origin) => {
|
|
170
180
|
const client = instance.rpcClients[id]
|
|
171
181
|
if (!msg.id) {
|
|
172
|
-
return getHandler(
|
|
182
|
+
return getHandler(
|
|
183
|
+
NOTIFICATIONS, msg, { debug: instance.debug }
|
|
184
|
+
)(instance, { client })(msg, origin)
|
|
173
185
|
}
|
|
174
186
|
if (Object.prototype.hasOwnProperty.call(client.callbacks, msg.id)) {
|
|
175
187
|
return getHandler(RESPONSES, msg, { debug: instance.debug })(instance, { client })(msg, origin)
|
|
@@ -189,7 +201,9 @@ const handleMessage = (instance, id) => async (msg, origin) => {
|
|
|
189
201
|
)
|
|
190
202
|
})
|
|
191
203
|
// TODO make one structure for handler functions
|
|
192
|
-
const errorObjectOrHandler = getHandler(REQUESTS, msg, { debug: instance.debug })(
|
|
204
|
+
const errorObjectOrHandler = getHandler(REQUESTS, msg, { debug: instance.debug })(
|
|
205
|
+
callInstance, instance, client, msg.params
|
|
206
|
+
)
|
|
193
207
|
const response = typeof errorObjectOrHandler === 'function' ? await errorObjectOrHandler() : errorObjectOrHandler
|
|
194
208
|
sendResponseMessage(client)(id, method, response)
|
|
195
209
|
}
|
|
@@ -202,18 +216,31 @@ const handleMessage = (instance, id) => async (msg, origin) => {
|
|
|
202
216
|
* @rtype Stamp
|
|
203
217
|
* @param {Object} param Init params object
|
|
204
218
|
* @param {String=} [param.name] Wallet name
|
|
205
|
-
* @param {Function} onConnection Call-back function for incoming AEPP connection
|
|
206
|
-
* @param {Function} onSubscription Call-back function for incoming AEPP account subscription
|
|
207
|
-
* @param {Function} onSign Call-back function for incoming AEPP sign request
|
|
208
|
-
* @param {Function} onAskAccounts Call-back function for incoming AEPP get address request
|
|
209
|
-
* @param {Function} onMessageSign Call-back function for incoming AEPP sign message request
|
|
219
|
+
* @param {Function} onConnection Call-back function for incoming AEPP connection
|
|
220
|
+
* @param {Function} onSubscription Call-back function for incoming AEPP account subscription
|
|
221
|
+
* @param {Function} onSign Call-back function for incoming AEPP sign request
|
|
222
|
+
* @param {Function} onAskAccounts Call-back function for incoming AEPP get address request
|
|
223
|
+
* @param {Function} onMessageSign Call-back function for incoming AEPP sign message request
|
|
224
|
+
* Second argument of incoming call-backs contain function for accept/deny request
|
|
210
225
|
* @param {Function} onDisconnect Call-back function for disconnect event
|
|
211
226
|
* @return {Object}
|
|
212
227
|
*/
|
|
213
228
|
export default Ae.compose(AccountMultiple, {
|
|
214
|
-
init ({
|
|
229
|
+
init ({
|
|
230
|
+
name,
|
|
231
|
+
onConnection,
|
|
232
|
+
onSubscription,
|
|
233
|
+
onSign,
|
|
234
|
+
onDisconnect,
|
|
235
|
+
onAskAccounts,
|
|
236
|
+
onMessageSign,
|
|
237
|
+
forceValidation = false,
|
|
238
|
+
debug = false
|
|
239
|
+
} = {}) {
|
|
215
240
|
this.debug = debug
|
|
216
|
-
const eventsHandlers = [
|
|
241
|
+
const eventsHandlers = [
|
|
242
|
+
'onConnection', 'onSubscription', 'onSign', 'onDisconnect', 'onMessageSign'
|
|
243
|
+
]
|
|
217
244
|
// CallBacks for events
|
|
218
245
|
this.onConnection = onConnection
|
|
219
246
|
this.onSubscription = onSubscription
|
|
@@ -224,7 +251,9 @@ export default Ae.compose(AccountMultiple, {
|
|
|
224
251
|
this.rpcClients = {}
|
|
225
252
|
|
|
226
253
|
eventsHandlers.forEach(event => {
|
|
227
|
-
if (!forceValidation && typeof this[event] !== 'function')
|
|
254
|
+
if (!forceValidation && typeof this[event] !== 'function') {
|
|
255
|
+
throw new Error(`Call-back for ${event} must be an function!`)
|
|
256
|
+
}
|
|
228
257
|
})
|
|
229
258
|
//
|
|
230
259
|
this.name = name
|
|
@@ -299,7 +328,8 @@ export default Ae.compose(AccountMultiple, {
|
|
|
299
328
|
* @return {String} Client ID
|
|
300
329
|
*/
|
|
301
330
|
addRpcClient (clientConnection) {
|
|
302
|
-
// @TODO detect if aepp has some history based on origin
|
|
331
|
+
// @TODO detect if aepp has some history based on origin????
|
|
332
|
+
// if yes use this instance for connection
|
|
303
333
|
const id = uuid()
|
|
304
334
|
this.rpcClients[id] = RpcClient({
|
|
305
335
|
id,
|
|
@@ -52,7 +52,10 @@ export default stampit({
|
|
|
52
52
|
scan (onDetected) {
|
|
53
53
|
const { wallets } = this
|
|
54
54
|
this.connection.connect(({ method, params }, origin, source) => {
|
|
55
|
-
if (
|
|
55
|
+
if (
|
|
56
|
+
!method || !params ||
|
|
57
|
+
method !== METHODS.wallet.readyToConnect || wallets[params.id]
|
|
58
|
+
) return
|
|
56
59
|
|
|
57
60
|
const wallet = {
|
|
58
61
|
...params,
|
|
@@ -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
|
|
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])
|
package/src/utils/bignumber.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
package/src/utils/crypto.js
CHANGED
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import bs58check from 'bs58check'
|
|
25
|
-
import ed2curve from 'ed2curve'
|
|
26
25
|
import nacl from 'tweetnacl'
|
|
27
26
|
import aesjs from 'aes-js'
|
|
28
27
|
import shajs from 'sha.js'
|
|
29
28
|
|
|
30
29
|
import { str2buf, toBytes } from './bytes'
|
|
30
|
+
import { decode } from '../tx/builder/helpers'
|
|
31
31
|
import { hash } from './crypto-ts'
|
|
32
32
|
|
|
33
33
|
export * from './crypto-ts'
|
|
@@ -56,7 +56,7 @@ export function getAddressFromPriv (secret) {
|
|
|
56
56
|
export function isAddressValid (address, prefix = 'ak') {
|
|
57
57
|
if (typeof address !== 'string') return false
|
|
58
58
|
try {
|
|
59
|
-
return
|
|
59
|
+
return decode(address, prefix).length === 32
|
|
60
60
|
} catch (e) {
|
|
61
61
|
return false
|
|
62
62
|
}
|
|
@@ -173,7 +173,7 @@ export function encodeUnsigned (value) {
|
|
|
173
173
|
* @return {String} - Contract address
|
|
174
174
|
*/
|
|
175
175
|
export function encodeContractAddress (owner, nonce) {
|
|
176
|
-
const publicKey =
|
|
176
|
+
const publicKey = decode(owner, 'ak')
|
|
177
177
|
const binary = Buffer.concat([publicKey, encodeUnsigned(nonce)])
|
|
178
178
|
return `ct_${encodeBase58Check(hash(binary))}`
|
|
179
179
|
}
|
|
@@ -192,7 +192,7 @@ export function generateKeyPairFromSecret (secret) {
|
|
|
192
192
|
|
|
193
193
|
/**
|
|
194
194
|
* Generate a random ED25519 keypair
|
|
195
|
-
* @rtype (raw: Boolean) => {publicKey: String, secretKey: String
|
|
195
|
+
* @rtype (raw: Boolean) => {publicKey: String | Buffer, secretKey: String | Buffer}
|
|
196
196
|
* @param {Boolean} raw - Whether to return raw (binary) keys
|
|
197
197
|
* @return {Object} Key pair
|
|
198
198
|
*/
|
|
@@ -296,20 +296,6 @@ export function aeEncodeKey (binaryKey) {
|
|
|
296
296
|
return `ak_${pubKeyAddress}`
|
|
297
297
|
}
|
|
298
298
|
|
|
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
299
|
/**
|
|
314
300
|
* Check key pair for validity
|
|
315
301
|
*
|
|
@@ -324,53 +310,3 @@ export function isValidKeypair (privateKey, publicKey) {
|
|
|
324
310
|
const signature = sign(message, privateKey)
|
|
325
311
|
return verify(message, signature, publicKey)
|
|
326
312
|
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* This function encrypts a message using base58check encoded and 'ak' prefixed
|
|
330
|
-
* publicKey such that only the corresponding secretKey will
|
|
331
|
-
* be able to decrypt
|
|
332
|
-
* @rtype (msg: String, publicKey: String) => Object
|
|
333
|
-
* @param {Buffer} msg - Data to encode
|
|
334
|
-
* @param {String} publicKey - Public key
|
|
335
|
-
* @return {Object}
|
|
336
|
-
*/
|
|
337
|
-
export function encryptData (msg, publicKey) {
|
|
338
|
-
const ephemeralKeyPair = nacl.box.keyPair()
|
|
339
|
-
const pubKeyUInt8Array = decodeBase58Check(assertedType(publicKey, 'ak'))
|
|
340
|
-
const nonce = nacl.randomBytes(nacl.box.nonceLength)
|
|
341
|
-
|
|
342
|
-
const encryptedMessage = nacl.box(
|
|
343
|
-
Buffer.from(msg),
|
|
344
|
-
nonce,
|
|
345
|
-
ed2curve.convertPublicKey(pubKeyUInt8Array),
|
|
346
|
-
ephemeralKeyPair.secretKey
|
|
347
|
-
)
|
|
348
|
-
|
|
349
|
-
return {
|
|
350
|
-
ciphertext: Buffer.from(encryptedMessage).toString('hex'),
|
|
351
|
-
ephemPubKey: Buffer.from(ephemeralKeyPair.publicKey).toString('hex'),
|
|
352
|
-
nonce: Buffer.from(nonce).toString('hex'),
|
|
353
|
-
version: 'x25519-xsalsa20-poly1305'
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* This function decrypt a message using secret key
|
|
359
|
-
* @rtype (secretKey: String, encryptedData: Object) => Buffer|null
|
|
360
|
-
* @param {String} secretKey - Secret key
|
|
361
|
-
* @param {Object} encryptedData - Encrypted data
|
|
362
|
-
* @return {Buffer|null}
|
|
363
|
-
*/
|
|
364
|
-
export function decryptData (secretKey, encryptedData) {
|
|
365
|
-
const receiverSecretKeyUint8Array = ed2curve.convertSecretKey(Buffer.from(secretKey, 'hex'))
|
|
366
|
-
const nonce = Buffer.from(encryptedData.nonce, 'hex')
|
|
367
|
-
const ciphertext = Buffer.from(encryptedData.ciphertext, 'hex')
|
|
368
|
-
const ephemPubKey = Buffer.from(encryptedData.ephemPubKey, 'hex')
|
|
369
|
-
const decrypted = nacl.box.open(
|
|
370
|
-
ciphertext,
|
|
371
|
-
nonce,
|
|
372
|
-
ephemPubKey,
|
|
373
|
-
receiverSecretKeyUint8Array
|
|
374
|
-
)
|
|
375
|
-
return decrypted ? Buffer.from(decrypted) : decrypted
|
|
376
|
-
}
|
package/src/utils/keystore.js
CHANGED
|
@@ -189,7 +189,14 @@ export async function recover (password, keyObject) {
|
|
|
189
189
|
* @param {Object=} options.kdfparams KDF parameters (default: constants.<kdf>).
|
|
190
190
|
* @return {Object}
|
|
191
191
|
*/
|
|
192
|
-
export async function dump (
|
|
192
|
+
export async function dump (
|
|
193
|
+
name,
|
|
194
|
+
password,
|
|
195
|
+
privateKey,
|
|
196
|
+
nonce = nacl.randomBytes(24),
|
|
197
|
+
salt = nacl.randomBytes(16),
|
|
198
|
+
options = {}
|
|
199
|
+
) {
|
|
193
200
|
const opt = Object.assign({}, DEFAULTS.crypto, options)
|
|
194
201
|
return marshal(
|
|
195
202
|
name,
|
|
@@ -208,7 +215,8 @@ export function validateKeyObj (obj) {
|
|
|
208
215
|
const missingRootKeys = root.filter(key => !Object.prototype.hasOwnProperty.call(obj, key))
|
|
209
216
|
if (missingRootKeys.length) throw new Error(`Invalid key file format. Require properties: ${missingRootKeys}`)
|
|
210
217
|
|
|
211
|
-
const missingCryptoKeys = cryptoKeys
|
|
218
|
+
const missingCryptoKeys = cryptoKeys
|
|
219
|
+
.filter(key => !Object.prototype.hasOwnProperty.call(obj.crypto, key))
|
|
212
220
|
if (missingCryptoKeys.length) throw new Error(`Invalid key file format. Require properties: ${missingCryptoKeys}`)
|
|
213
221
|
|
|
214
222
|
return true
|
package/src/utils/other.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { snakeToPascal, pascalToSnake } from './string'
|
|
2
2
|
|
|
3
|
-
export const pause = async (duration: number): Promise<
|
|
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(
|
|
3
|
+
.split(/[-+]/)[0].split('.').map(i => +i)
|
|
4
4
|
|
|
5
5
|
const versionComponents = getComponents(version)
|
|
6
6
|
const geComponents = getComponents(geVersion)
|
package/src/utils/swagger.js
CHANGED
|
@@ -39,15 +39,24 @@ 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 (
|
|
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
|
|
|
49
|
-
if (
|
|
50
|
-
|
|
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
|
+
) {
|
|
51
60
|
spec.schemes = ['https']
|
|
52
61
|
}
|
|
53
62
|
|
|
@@ -57,11 +66,12 @@ export default async (specUrl, { spec, internalUrl, disableBigNumbers, disableCa
|
|
|
57
66
|
url,
|
|
58
67
|
spec,
|
|
59
68
|
responseInterceptor: response => {
|
|
60
|
-
if (
|
|
69
|
+
if (response.text === '' || response.text?.size === 0) return response
|
|
61
70
|
const body = jsonImp.parse(response.text)
|
|
62
|
-
|
|
71
|
+
Object.assign(response, {
|
|
63
72
|
body: disableCaseConversion ? body : pascalizeKeys(body)
|
|
64
73
|
})
|
|
74
|
+
return (responseInterceptor && responseInterceptor(response)) || response
|
|
65
75
|
}
|
|
66
76
|
})
|
|
67
77
|
}))
|
|
@@ -92,11 +102,13 @@ export default async (specUrl, { spec, internalUrl, disableBigNumbers, disableCa
|
|
|
92
102
|
const opSpec = opSpecs[opId]
|
|
93
103
|
const parameters = [
|
|
94
104
|
...opSpec.parameters,
|
|
95
|
-
...opSpec.requestBody
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
...opSpec.requestBody
|
|
106
|
+
? [{
|
|
107
|
+
required: opSpec.requestBody.required,
|
|
108
|
+
schema: Object.values(opSpec.requestBody.content)[0].schema,
|
|
109
|
+
name: '__requestBody'
|
|
110
|
+
}]
|
|
111
|
+
: []
|
|
100
112
|
]
|
|
101
113
|
const required = parameters.filter(param => param.required).map(p => p.name)
|
|
102
114
|
if (args.length < required.length) throw new Error('swagger: Not enough arguments')
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import * as R from 'ramda'
|
|
2
|
-
import { unpackTx } from '../../tx/builder'
|
|
3
|
-
import { decodeEvents as unpackEvents, transform, transformDecodedData, validateArguments } from './transformation'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Get function schema from contract ACI object
|
|
7
|
-
* @param {Object} aci Contract ACI object
|
|
8
|
-
* @param {String} name Function name
|
|
9
|
-
* @param external
|
|
10
|
-
* @return {Object} function ACI
|
|
11
|
-
*/
|
|
12
|
-
export function getFunctionACI (aci, name, { external }) {
|
|
13
|
-
if (!aci) throw new Error('ACI required')
|
|
14
|
-
const fn = aci.functions.find(f => f.name === name)
|
|
15
|
-
if (!fn && name !== 'init') throw new Error(`Function ${name} doesn't exist in contract`)
|
|
16
|
-
|
|
17
|
-
return {
|
|
18
|
-
...fn,
|
|
19
|
-
bindings: [
|
|
20
|
-
{
|
|
21
|
-
state: aci.state,
|
|
22
|
-
type_defs: aci.type_defs,
|
|
23
|
-
name: aci.name
|
|
24
|
-
},
|
|
25
|
-
...external.map(R.pick(['state', 'type_defs', 'name']))
|
|
26
|
-
],
|
|
27
|
-
event: aci.event ? aci.event.variant : []
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Build contract methods base on ACI
|
|
33
|
-
* @return {Object} Contract instance methods
|
|
34
|
-
*/
|
|
35
|
-
export const buildContractMethods = (instance) => () => ({
|
|
36
|
-
...instance.aci
|
|
37
|
-
? instance
|
|
38
|
-
.aci
|
|
39
|
-
.functions
|
|
40
|
-
.reduce(
|
|
41
|
-
(acc, { name, arguments: aciArgs, stateful }) => ({
|
|
42
|
-
...acc,
|
|
43
|
-
[name]: Object.assign(
|
|
44
|
-
function () {
|
|
45
|
-
const { opt, args } = parseArguments(aciArgs)(arguments)
|
|
46
|
-
if (name === 'init') return instance.deploy(args, opt)
|
|
47
|
-
return instance.call(name, args, { callStatic: !stateful, ...opt })
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
get () {
|
|
51
|
-
const { opt, args } = parseArguments(aciArgs)(arguments)
|
|
52
|
-
return instance.call(name, args, { ...opt, callStatic: true })
|
|
53
|
-
},
|
|
54
|
-
send () {
|
|
55
|
-
const { opt, args } = parseArguments(aciArgs)(arguments)
|
|
56
|
-
if (name === 'init') return instance.deploy(args, opt)
|
|
57
|
-
return instance.call(name, args, { ...opt, callStatic: false })
|
|
58
|
-
},
|
|
59
|
-
decodeEvents (events) {
|
|
60
|
-
return instance.decodeEvents(name, events)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
)
|
|
64
|
-
}),
|
|
65
|
-
{}
|
|
66
|
-
)
|
|
67
|
-
: {},
|
|
68
|
-
...instance.aci ? {
|
|
69
|
-
init: Object.assign(
|
|
70
|
-
function () {
|
|
71
|
-
const { arguments: aciArgs } = getFunctionACI(instance.aci, 'init', { external: instance.externalAci })
|
|
72
|
-
const { opt, args } = parseArguments(aciArgs)(arguments)
|
|
73
|
-
return instance.deploy(args, opt)
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
get () {
|
|
77
|
-
const { arguments: aciArgs } = getFunctionACI(instance.aci, 'init', { external: instance.externalAci })
|
|
78
|
-
const { opt, args } = parseArguments(aciArgs)(arguments)
|
|
79
|
-
return instance.deploy(args, { ...opt, callStatic: true })
|
|
80
|
-
},
|
|
81
|
-
send () {
|
|
82
|
-
const { arguments: aciArgs } = getFunctionACI(instance.aci, 'init', { external: instance.externalAci })
|
|
83
|
-
const { opt, args } = parseArguments(aciArgs)(arguments)
|
|
84
|
-
return instance.deploy(args, { ...opt, callStatic: false })
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
)
|
|
88
|
-
} : {}
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
export const parseArguments = (aciArgs = []) => (args) => ({
|
|
92
|
-
opt: args.length > aciArgs.length ? R.last(args) : {},
|
|
93
|
-
args: Object.values(args).slice(0, aciArgs.length)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
export const unpackByteCode = (bytecode) => unpackTx(bytecode, false, 'cb').tx
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Validated contract call arguments using contract ACI
|
|
100
|
-
* @function validateCallParams
|
|
101
|
-
* @rtype (aci: Object, params: Array) => Object
|
|
102
|
-
* @param {Object} aci Contract ACI
|
|
103
|
-
* @param {Array} params Contract call arguments
|
|
104
|
-
* @return Promise{Array} Object with validation errors
|
|
105
|
-
*/
|
|
106
|
-
export const prepareArgsForEncode = async (aci, params) => {
|
|
107
|
-
if (!aci || !aci.arguments) return params
|
|
108
|
-
// Validation
|
|
109
|
-
if (aci.arguments.length > params.length) {
|
|
110
|
-
throw new Error(`Function "${aci.name}" require ${aci.arguments.length} arguments of types [${aci.arguments.map(a => JSON.stringify(a.type))}] but get [${params.map(JSON.stringify)}]`)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
validateArguments(aci, params)
|
|
114
|
-
const bindings = aci.bindings
|
|
115
|
-
// Cast argument from JS to Sophia type
|
|
116
|
-
return Promise.all(aci.arguments.map(async ({ type }, i) => transform(type, params[i], {
|
|
117
|
-
bindings
|
|
118
|
-
})))
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export const decodeEvents = (events, fnACI) => {
|
|
122
|
-
if (!fnACI || !fnACI.event || !fnACI.event.length) return []
|
|
123
|
-
|
|
124
|
-
const eventsSchema = fnACI.event.map(e => {
|
|
125
|
-
const name = Object.keys(e)[0]
|
|
126
|
-
return { name, types: e[name] }
|
|
127
|
-
})
|
|
128
|
-
return unpackEvents(events, { schema: eventsSchema })
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export const decodeCallResult = async (result, fnACI, opt) => {
|
|
132
|
-
return {
|
|
133
|
-
decodedResult: await transformDecodedData(
|
|
134
|
-
fnACI.returns,
|
|
135
|
-
await result.decode(),
|
|
136
|
-
{ ...opt, bindings: fnACI.bindings }
|
|
137
|
-
),
|
|
138
|
-
decodedEvents: decodeEvents(result.result.log, fnACI)
|
|
139
|
-
}
|
|
140
|
-
}
|