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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/dist/aepp-sdk.browser-script.js +1 -1
  2. package/dist/aepp-sdk.browser-script.js.LICENSE.txt +0 -9
  3. package/dist/aepp-sdk.browser-script.js.map +1 -1
  4. package/dist/aepp-sdk.browser.js +1 -1
  5. package/dist/aepp-sdk.browser.js.map +1 -1
  6. package/dist/aepp-sdk.js +1 -1
  7. package/dist/aepp-sdk.js.map +1 -1
  8. package/es/account/base.js +30 -122
  9. package/es/account/base.js.map +1 -1
  10. package/es/account/memory.js +17 -19
  11. package/es/account/memory.js.map +1 -1
  12. package/es/account/multiple.js +73 -164
  13. package/es/account/multiple.js.map +1 -1
  14. package/es/ae/aens.js +164 -599
  15. package/es/ae/aens.js.map +1 -1
  16. package/es/ae/contract.js +82 -759
  17. package/es/ae/contract.js.map +1 -1
  18. package/es/ae/index.js +78 -315
  19. package/es/ae/index.js.map +1 -1
  20. package/es/ae/oracle.js +130 -498
  21. package/es/ae/oracle.js.map +1 -1
  22. package/es/chain/index.js +1 -1
  23. package/es/chain/index.js.map +1 -1
  24. package/es/chain/node.js +288 -1008
  25. package/es/chain/node.js.map +1 -1
  26. package/es/channel/handlers.js +597 -1086
  27. package/es/channel/handlers.js.map +1 -1
  28. package/es/channel/index.js +203 -451
  29. package/es/channel/index.js.map +1 -1
  30. package/es/channel/internal.js +129 -301
  31. package/es/channel/internal.js.map +1 -1
  32. package/es/contract/aci/index.js +319 -480
  33. package/es/contract/aci/index.js.map +1 -1
  34. package/es/contract/aci/transformation.js +35 -711
  35. package/es/contract/aci/transformation.js.map +1 -1
  36. package/es/contract/compiler.js +129 -203
  37. package/es/contract/compiler.js.map +1 -1
  38. package/es/contract/ga/helpers.js +16 -114
  39. package/es/contract/ga/helpers.js.map +1 -1
  40. package/es/contract/ga/index.js +101 -242
  41. package/es/contract/ga/index.js.map +1 -1
  42. package/es/contract/index.js +1 -1
  43. package/es/contract/index.js.map +1 -1
  44. package/es/index.js +1 -2
  45. package/es/index.js.map +1 -1
  46. package/es/node-pool/index.js +54 -73
  47. package/es/node-pool/index.js.map +1 -1
  48. package/es/node.js +56 -157
  49. package/es/node.js.map +1 -1
  50. package/es/other.d.ts +1 -1
  51. package/es/tx/builder/helpers.js +38 -75
  52. package/es/tx/builder/helpers.js.map +1 -1
  53. package/es/tx/builder/index.js +196 -294
  54. package/es/tx/builder/index.js.map +1 -1
  55. package/es/tx/builder/schema.js +577 -459
  56. package/es/tx/builder/schema.js.map +1 -1
  57. package/es/tx/index.js +1 -1
  58. package/es/tx/index.js.map +1 -1
  59. package/es/tx/tx-object.js +105 -132
  60. package/es/tx/tx-object.js.map +1 -1
  61. package/es/tx/tx.js +808 -1628
  62. package/es/tx/tx.js.map +1 -1
  63. package/es/tx/validator.js +132 -268
  64. package/es/tx/validator.js.map +1 -1
  65. package/es/utils/aepp-wallet-communication/connection/browser-runtime.js +17 -21
  66. package/es/utils/aepp-wallet-communication/connection/browser-runtime.js.map +1 -1
  67. package/es/utils/aepp-wallet-communication/connection/browser-window-message.js +38 -74
  68. package/es/utils/aepp-wallet-communication/connection/browser-window-message.js.map +1 -1
  69. package/es/utils/aepp-wallet-communication/content-script-bridge.js +14 -15
  70. package/es/utils/aepp-wallet-communication/content-script-bridge.js.map +1 -1
  71. package/es/utils/aepp-wallet-communication/helpers.js +60 -105
  72. package/es/utils/aepp-wallet-communication/helpers.js.map +1 -1
  73. package/es/utils/aepp-wallet-communication/rpc/aepp-rpc.js +179 -510
  74. package/es/utils/aepp-wallet-communication/rpc/aepp-rpc.js.map +1 -1
  75. package/es/utils/aepp-wallet-communication/rpc/rpc-client.js +70 -89
  76. package/es/utils/aepp-wallet-communication/rpc/rpc-client.js.map +1 -1
  77. package/es/utils/aepp-wallet-communication/rpc/wallet-rpc.js +353 -600
  78. package/es/utils/aepp-wallet-communication/rpc/wallet-rpc.js.map +1 -1
  79. package/es/utils/aepp-wallet-communication/schema.js +43 -39
  80. package/es/utils/aepp-wallet-communication/schema.js.map +1 -1
  81. package/es/utils/aepp-wallet-communication/wallet-detector.js +32 -58
  82. package/es/utils/aepp-wallet-communication/wallet-detector.js.map +1 -1
  83. package/es/utils/amount-formatter.js +41 -61
  84. package/es/utils/amount-formatter.js.map +1 -1
  85. package/es/utils/async-init.js +28 -64
  86. package/es/utils/async-init.js.map +1 -1
  87. package/es/utils/bignumber.js +3 -11
  88. package/es/utils/bignumber.js.map +1 -1
  89. package/es/utils/bytes.js +5 -9
  90. package/es/utils/bytes.js.map +1 -1
  91. package/es/utils/crypto.js +47 -62
  92. package/es/utils/crypto.js.map +1 -1
  93. package/es/utils/hd-wallet.js +45 -81
  94. package/es/utils/hd-wallet.js.map +1 -1
  95. package/es/utils/json-big.js +16 -49
  96. package/es/utils/json-big.js.map +1 -1
  97. package/es/utils/keystore.js +81 -246
  98. package/es/utils/keystore.js.map +1 -1
  99. package/es/utils/mptree.js +88 -134
  100. package/es/utils/mptree.js.map +1 -1
  101. package/es/utils/other.js +10 -60
  102. package/es/utils/other.js.map +1 -1
  103. package/es/utils/semver-satisfies.js +9 -28
  104. package/es/utils/semver-satisfies.js.map +1 -1
  105. package/es/utils/string.js +4 -13
  106. package/es/utils/string.js.map +1 -1
  107. package/es/utils/swagger.js +85 -224
  108. package/es/utils/swagger.js.map +1 -1
  109. package/package.json +44 -40
  110. package/src/account/multiple.js +18 -19
  111. package/src/ae/aens.js +25 -21
  112. package/src/ae/contract.js +32 -163
  113. package/src/ae/index.js +3 -3
  114. package/src/ae/oracle.js +18 -14
  115. package/src/chain/node.js +2 -4
  116. package/src/channel/handlers.js +0 -1
  117. package/src/channel/index.js +4 -5
  118. package/src/contract/aci/index.js +221 -102
  119. package/src/contract/aci/transformation.js +30 -422
  120. package/src/contract/compiler.js +45 -4
  121. package/src/contract/ga/helpers.js +1 -8
  122. package/src/contract/ga/index.js +13 -11
  123. package/src/index.js +0 -2
  124. package/src/node-pool/index.js +21 -12
  125. package/src/node.js +22 -26
  126. package/src/tx/builder/index.js +2 -1
  127. package/src/tx/builder/schema.js +2 -1
  128. package/src/tx/tx.js +147 -143
  129. package/src/tx/validator.js +9 -7
  130. package/src/utils/aepp-wallet-communication/rpc/aepp-rpc.js +1 -3
  131. package/src/utils/aepp-wallet-communication/rpc/wallet-rpc.js +3 -3
  132. package/src/utils/aepp-wallet-communication/schema.js +1 -3
  133. package/src/utils/bignumber.ts +2 -1
  134. package/src/utils/other.ts +1 -1
  135. package/src/utils/semver-satisfies.ts +1 -1
  136. package/src/utils/swagger.js +14 -7
  137. package/src/contract/aci/helpers.js +0 -140
@@ -1,9 +1,7 @@
1
- import Joi from 'joi-browser'
2
- import { isHex } from '../../utils/string'
3
1
  import { toBytes } from '../../utils/bytes'
4
2
  import { decode } from '../../tx/builder/helpers'
5
3
  import { parseBigNumber } from '../../utils/bignumber'
6
- import { isAddressValid, addressFromDecimal, hash } from '../../utils/crypto'
4
+ import { addressFromDecimal, hash } from '../../utils/crypto'
7
5
 
8
6
  export const SOPHIA_TYPES = [
9
7
  'int',
@@ -24,441 +22,51 @@ export const SOPHIA_TYPES = [
24
22
  ].reduce((acc, type) => ({ ...acc, [type]: type }), { ChainTtl: 'Chain.ttl' })
25
23
 
26
24
  /**
27
- * Transform decoded event to JS type
28
- * @param {Object[]} events Array of events
29
- * @param {Object} [options={}] Options
30
- * @param {Object} [options.schema=[]] SC function ACI schema
25
+ * Decode events fields
26
+ * @param {Object[]} events Array of events with encoded fields
27
+ * @param {Array} schemas Smart contract event ACI schemas
31
28
  * @return {Object}
32
29
  */
33
- export function decodeEvents (events, options = { schema: [] }) {
34
- if (!events.length) return []
35
-
36
- return events.map(l => {
37
- const [eName, ...eParams] = l.topics
38
- const hexHash = toBytes(eName, true).toString('hex')
39
- const { schema } = options.schema
40
- .reduce(
41
- (acc, el) => {
42
- if (hash(el.name).toString('hex') === hexHash) {
43
- l.name = el.name
44
- return {
45
- schema: el.types,
46
- name: el.name
47
- }
48
- }
49
- return acc
50
- },
51
- { schema: [] }
52
- )
53
- const { decoded } = schema.reduce((acc, el) => {
54
- if (el === SOPHIA_TYPES.string) {
55
- return { decoded: [...acc.decoded, transformEvent(l.data, el)], params: acc.params }
56
- }
57
- const [event, ...tail] = acc.params
58
- return { decoded: [...acc.decoded, transformEvent(event, el)], params: tail }
59
- }, { decoded: [], params: eParams })
30
+ export const decodeEvents = (events, schemas = []) => events.reduce((acc, event) => {
31
+ const [nameHash, ...params] = event.topics
32
+ const schema = schemas.find((s) => hash(s.name).equals(toBytes(nameHash, true)))
33
+ if (!schema) return acc
34
+ const stringCount = schema.types.filter(t => t === SOPHIA_TYPES.string).length
35
+ if (stringCount > 1) throw new Error(`Event schema contains more than one string: ${schema.types}`)
36
+ const topicsCount = schema.types.length - stringCount
37
+ if (topicsCount !== params.length) {
38
+ throw new Error(`Schema defines ${topicsCount} types, but ${params.length} topics present`)
39
+ }
60
40
 
61
- return {
62
- ...l,
63
- decoded
64
- }
41
+ acc.push({
42
+ ...event,
43
+ name: schema.name,
44
+ decoded: schema.types.map((type) =>
45
+ decodeEventField(type === SOPHIA_TYPES.string ? event.data : params.shift(), type))
65
46
  })
66
- }
47
+
48
+ return acc
49
+ }, [])
67
50
 
68
51
  /**
69
52
  * Transform Event based on type
70
- * @param {String|Number} event Event data
53
+ * @param {String|Number} field Event data
71
54
  * @param {String} type Event type from schema
72
55
  * @return {*}
73
56
  */
74
- export function transformEvent (event, type) {
57
+ function decodeEventField (field, type) {
75
58
  switch (type) {
76
59
  case SOPHIA_TYPES.int:
77
- return parseBigNumber(event)
60
+ return parseBigNumber(field)
78
61
  case SOPHIA_TYPES.bool:
79
- return !!event
80
- case SOPHIA_TYPES.hash:
81
- return toBytes(event, true).toString('hex')
82
- case SOPHIA_TYPES.address:
83
- return addressFromDecimal(event).split('_')[1]
84
- case SOPHIA_TYPES.string:
85
- return decode(event).toString('utf-8')
86
- default:
87
- return toBytes(event, true)
88
- }
89
- }
90
-
91
- export function injectVars (t, aciType) {
92
- const [[baseType, generic]] = Object.entries(aciType.typedef)
93
- const [[, varianValue]] = Object.entries(t)
94
- switch (baseType) {
95
- case SOPHIA_TYPES.variant:
96
- return {
97
- [baseType]: generic.map(el => {
98
- const [tag, gen] = Object.entries(el)[0]
99
- return {
100
- [tag]: gen.map(type => {
101
- const index = aciType.vars.map(e => e.name).indexOf(type)
102
- return index === -1
103
- ? type
104
- : varianValue[index]
105
- })
106
- }
107
- })
108
- }
109
- }
110
- }
111
-
112
- /**
113
- * Ling Type Defs
114
- * @param t
115
- * @param bindings
116
- * @return {Object}
117
- */
118
- export function linkTypeDefs (t, bindings) {
119
- const [root, typeDef] = typeof t === 'object' ? Object.keys(t)[0].split('.') : t.split('.')
120
- const contractTypeDefs = bindings.find(c => c.name === root)
121
- const aciType = [
122
- ...contractTypeDefs.type_defs,
123
- { name: 'state', typedef: contractTypeDefs.state, vars: [] }
124
- ].find(({ name }) => name === typeDef)
125
- if (aciType.vars.length) {
126
- aciType.typedef = injectVars(t, aciType)
127
- }
128
- return isTypedDefOrState(aciType.typedef, bindings) ? linkTypeDefs(aciType.typedef, bindings) : aciType.typedef
129
- }
130
-
131
- const isTypedDefOrState = (t, bindings) => {
132
- if (!['string', 'object'].includes(typeof t)) return false
133
-
134
- t = typeof t === 'object' ? Object.keys(t)[0] : t
135
- const [root, ...path] = t.split('.')
136
- // Remote Contract Address
137
- if (!path.length) return false
138
- return bindings.map(c => c.name).includes(root)
139
- }
140
-
141
- const isRemoteAddress = (t) => {
142
- if (typeof t !== 'string') return false
143
- const [root, ...path] = t.split('.')
144
- return !path.length && !Object.values(SOPHIA_TYPES).includes(root)
145
- }
146
-
147
- /**
148
- * Parse sophia type
149
- * @param type
150
- * @param returnType
151
- * @return {Object}
152
- */
153
- export function readType (type, { bindings } = {}) {
154
- let [t] = Array.isArray(type) ? type : [type]
155
-
156
- // If remote address
157
- if (isRemoteAddress(t)) return { t: SOPHIA_TYPES.address }
158
- // Link State and typeDef
159
- if (isTypedDefOrState(t, bindings)) t = linkTypeDefs(t, bindings)
160
- // Map, Tuple, List, Record, Bytes
161
- if (typeof t === 'object') {
162
- const [[baseType, generic]] = Object.entries(t)
163
- return { t: baseType, generic }
164
- }
165
- // Base types
166
- if (typeof t === 'string') return { t }
167
- }
168
-
169
- // FUNCTION ARGUMENTS TRANSFORMATION ↓↓↓
170
-
171
- /**
172
- * Transform JS type to Sophia-type
173
- * @param type
174
- * @param value
175
- * @param bindings
176
- * @return {string}
177
- */
178
- export function transform (type, value, { bindings } = {}) {
179
- const { t, generic } = readType(type, { bindings })
180
-
181
- switch (t) {
182
- case SOPHIA_TYPES.ChainTtl:
183
- return `${value}`
184
- case SOPHIA_TYPES.string:
185
- return `"${value}"`
186
- case SOPHIA_TYPES.list:
187
- return `[${value.map(el => transform(generic, el, { bindings }))}]`
188
- case SOPHIA_TYPES.tuple:
189
- return `(${value.map((el, i) => transform(generic[i], el, {
190
- bindings
191
- }))})`
192
- case SOPHIA_TYPES.option: {
193
- return value === undefined ? 'None' : `Some(${transform(generic, value, {
194
- bindings
195
- })})`
196
- }
62
+ return !!field
197
63
  case SOPHIA_TYPES.hash:
198
- case SOPHIA_TYPES.bytes:
199
- case SOPHIA_TYPES.signature:
200
- if (typeof value === 'string') {
201
- if (isHex(value)) return `#${value}`
202
- if (isAddressValid(value)) return `#${decode(value).toString('hex')}`
203
- }
204
- return `#${Buffer.from(value).toString('hex')}`
205
- case SOPHIA_TYPES.record:
206
- return `{${generic.reduce(
207
- (acc, { name, type }, i) => {
208
- acc += `${i !== 0 ? ',' : ''}${name} = ${transform(type, value[name], {
209
- bindings
210
- })}`
211
- return acc
212
- },
213
- ''
214
- )}}`
215
- case SOPHIA_TYPES.map:
216
- return transformMap(value, generic, { bindings })
217
- case SOPHIA_TYPES.variant:
218
- return transformVariant(value, generic, { bindings })
219
- }
220
-
221
- return `${value}`
222
- }
223
-
224
- export function transformVariant (value, generic, { bindings }) {
225
- const [[variant, variantArgs]] = typeof value === 'string' ? [[value, []]] : Object.entries(value)
226
- const [[v, type]] = Object.entries(generic.find(o => Object.keys(o)[0].toLowerCase() === variant.toLowerCase()))
227
- return `${v}${!type.length
228
- ? ''
229
- : `(${variantArgs.slice(0, type.length).map((el, i) => transform(type[i], el, {
230
- bindings
231
- }))})`
232
- }`
233
- }
234
-
235
- export function transformMap (value, generic, { bindings }) {
236
- if (!Array.isArray(value)) {
237
- if (value.entries) value = Array.from(value.entries())
238
- else if (value instanceof Object) value = Object.entries(value)
239
- }
240
-
241
- return [
242
- '{',
243
- value
244
- .map(([key, value]) => [
245
- `[${transform(generic[0], key, { bindings })}]`,
246
- transform(generic[1], value, { bindings })
247
- ].join(' = '))
248
- .join(),
249
- '}'
250
- ].join('')
251
- }
252
-
253
- // FUNCTION RETURN VALUE TRANSFORMATION ↓↓↓
254
-
255
- /**
256
- * Transform decoded data to JS type
257
- * @param aci
258
- * @param result
259
- * @param transformDecodedData
260
- * @return {*}
261
- */
262
- export function transformDecodedData (aci, result, { skipTransformDecoded = false, addressPrefix = 'ak', bindings } = {}) {
263
- if (skipTransformDecoded) return result
264
- const { t, generic } = readType(aci, { bindings })
265
-
266
- switch (t) {
267
- case SOPHIA_TYPES.bool:
268
- return !!result
64
+ return toBytes(field, true).toString('hex')
269
65
  case SOPHIA_TYPES.address:
270
- return result === 0
271
- ? 0
272
- : result
273
- case SOPHIA_TYPES.hash:
274
- case SOPHIA_TYPES.bytes:
275
- case SOPHIA_TYPES.signature:
276
- return result.split('#')[1]
277
- case SOPHIA_TYPES.map: {
278
- const [keyT, valueT] = generic
279
- return result
280
- .reduce(
281
- (acc, [key, val]) => {
282
- key = transformDecodedData(keyT, key, { bindings })
283
- val = transformDecodedData(valueT, val, { bindings })
284
- acc.push([key, val])
285
- return acc
286
- },
287
- []
288
- )
289
- }
290
- case SOPHIA_TYPES.option: {
291
- if (result === 'None') return undefined
292
- const [[variantType, [value]]] = Object.entries(result)
293
- return variantType === 'Some' ? transformDecodedData(generic, value, { bindings }) : undefined
294
- }
295
- case SOPHIA_TYPES.list:
296
- return result.map((value) => transformDecodedData(generic, value, { bindings }))
297
- case SOPHIA_TYPES.tuple:
298
- return result.map((value, i) => { return transformDecodedData(generic[i], value, { bindings }) })
299
- case SOPHIA_TYPES.record: {
300
- const genericMap = generic.reduce((acc, val) => ({ ...acc, [val.name]: { type: val.type } }), {})
301
- return Object.entries(result).reduce(
302
- (acc, [name, value]) =>
303
- ({
304
- ...acc,
305
- [name]: transformDecodedData(genericMap[name].type, value, { bindings })
306
- }),
307
- {}
308
- )
309
- }
310
- }
311
- return result
312
- }
313
-
314
- // FUNCTION ARGUMENTS VALIDATION ↓↓↓
315
-
316
- /**
317
- * Prepare Joi validation schema for sophia types
318
- * @param type
319
- * @param bindings
320
- * @return {Object} JoiSchema
321
- */
322
- export function prepareSchema (type, { bindings } = {}) {
323
- const { t, generic } = readType(type, { bindings })
324
-
325
- switch (t) {
326
- case SOPHIA_TYPES.int:
327
- return Joi.number().error(getJoiErrorMsg)
328
- case SOPHIA_TYPES.variant:
329
- return Joi.alternatives().try([
330
- Joi.string().valid(
331
- ...generic.reduce((acc, el) => {
332
- const [[t, g]] = Object.entries(el)
333
- if (!g || !g.length) acc.push(t)
334
- return acc
335
- }, [])
336
- ),
337
- Joi.object(generic
338
- .reduce(
339
- (acc, el) => {
340
- const variant = Object.keys(el)[0]
341
- return { ...acc, [variant]: Joi.array() }
342
- },
343
- {})
344
- ).or(...generic.map(e => Object.keys(e)[0]))
345
- ])
346
- case SOPHIA_TYPES.ChainTtl:
347
- return Joi.string().error(getJoiErrorMsg)
66
+ return addressFromDecimal(field)
348
67
  case SOPHIA_TYPES.string:
349
- return Joi.string().error(getJoiErrorMsg)
350
- case SOPHIA_TYPES.address:
351
- return Joi.string().regex(/^(ak_|ct_|ok_|oq_)/).error(getJoiErrorMsg)
352
- case SOPHIA_TYPES.bool:
353
- return Joi.boolean().error(getJoiErrorMsg)
354
- case SOPHIA_TYPES.list:
355
- return Joi.array().items(prepareSchema(generic, { bindings })).error(getJoiErrorMsg)
356
- case SOPHIA_TYPES.tuple:
357
- return Joi.array().ordered(generic.map(type => prepareSchema(type, { bindings }).required())).label('Tuple argument').error(getJoiErrorMsg)
358
- case SOPHIA_TYPES.record:
359
- return Joi.object(
360
- generic.reduce((acc, { name, type }) => ({ ...acc, [name]: prepareSchema(type, { bindings }) }), {})
361
- ).error(getJoiErrorMsg)
362
- case SOPHIA_TYPES.hash:
363
- return JoiBinary.binary().bufferCheck(32).error(getJoiErrorMsg)
364
- case SOPHIA_TYPES.bytes:
365
- return JoiBinary.binary().bufferCheck(generic).error(getJoiErrorMsg)
366
- case SOPHIA_TYPES.signature:
367
- return JoiBinary.binary().bufferCheck(64).error(getJoiErrorMsg)
368
- case SOPHIA_TYPES.option:
369
- return prepareSchema(generic, { bindings }).optional().error(getJoiErrorMsg)
370
- // @Todo Need to transform Map to Array of arrays before validating it
371
- // case SOPHIA_TYPES.map:
372
- // return Joi.array().items(Joi.array().ordered(generic.map(type => prepareSchema(type))))
68
+ return decode(field).toString('utf-8')
373
69
  default:
374
- return Joi.any()
375
- }
376
- }
377
-
378
- /**
379
- * Parse Joi validation error message
380
- * @param errors
381
- * @return {Object} JoiError
382
- */
383
- export function getJoiErrorMsg (errors) {
384
- return errors.map(err => {
385
- const { path, type, context } = err
386
- let value = Object.prototype.hasOwnProperty.call(context, 'value') ? context.value : context.label
387
- value = typeof value === 'object' ? JSON.stringify(value).slice(1).slice(0, -1) : value
388
- switch (type) {
389
- case 'string.base':
390
- return ({ ...err, message: `Value "${value}" at path: [${path}] not a string` })
391
- case 'number.base':
392
- return ({ ...err, message: `Value "${value}" at path: [${path}] not a number` })
393
- case 'boolean.base':
394
- return ({ ...err, message: `Value "${value}" at path: [${path}] not a boolean` })
395
- case 'array.base':
396
- return ({ ...err, message: `Value "${value}" at path: [${path}] not a array` })
397
- case 'object.base':
398
- return ({ ...err, message: `Value '${value}' at path: [${path}] not a object` })
399
- case 'object.type':
400
- return ({ ...err, message: `Value '${value}' at path: [${path}] not a ${context.type}` })
401
- case 'binary.bufferCheck':
402
- return ({
403
- ...err,
404
- message: `Value '${Buffer.from(value).toString('hex')}' at path: [${path}] not a ${context.size} bytes`
405
- })
406
- default:
407
- return err
408
- }
409
- })
410
- }
411
-
412
- /**
413
- * Custom Joi Validator for binary type
414
- */
415
- const JoiBinary = Joi.extend((joi) => ({
416
- name: 'binary',
417
- base: joi.any(),
418
- pre (value, state, options) {
419
- if (options.convert && typeof value === 'string') {
420
- if (isAddressValid(value)) {
421
- return decode(value)
422
- }
423
- try {
424
- return Buffer.from(value, 'hex')
425
- } catch (e) { return undefined }
426
- }
427
-
428
- return Buffer.from(value)
429
- },
430
- rules: [
431
- {
432
- name: 'bufferCheck',
433
- params: {
434
- size: joi.number().required()
435
- },
436
- validate (params, value, state, options) {
437
- if (!Buffer.isBuffer(value)) {
438
- return this.createError('binary.base', { value }, state, options)
439
- }
440
- if (value.length !== params.size) {
441
- return this.createError('binary.bufferCheck', { value, size: params.size }, state, options)
442
- }
443
-
444
- return value
445
- }
446
- }
447
- ]
448
- }))
449
-
450
- /**
451
- * Validation contract function arguments
452
- * @param aci
453
- * @param params
454
- */
455
- export function validateArguments (aci, params) {
456
- const validationSchema = Joi.array().ordered(
457
- aci.arguments
458
- .map(({ type }, i) => prepareSchema(type, { bindings: aci.bindings }).label(`[${params[i]}]`))
459
- ).sparse(true).label('Argument')
460
- const { error } = Joi.validate(params, validationSchema, { abortEarly: false })
461
- if (error) {
462
- throw error
70
+ return toBytes(field, true)
463
71
  }
464
72
  }
@@ -52,12 +52,29 @@ export default AsyncInit.compose(ContractBase, {
52
52
  compilerUrl = compilerUrl.replace(/\/$/, '')
53
53
  const client = await genSwaggerClient(`${compilerUrl}/api`, {
54
54
  disableBigNumbers: true,
55
- disableCaseConversion: true
55
+ disableCaseConversion: true,
56
+ responseInterceptor: response => {
57
+ if (response.ok) return
58
+ let message = `${new URL(response.url).pathname.slice(1)} error`
59
+ if (response.body.reason) {
60
+ message += ': ' + response.body.reason +
61
+ (response.body.parameter ? ` in ${response.body.parameter}` : '') +
62
+ // TODO: revising after improving documentation https://github.com/aeternity/aesophia_http/issues/78
63
+ (response.body.info ? ` (${JSON.stringify(response.body.info)})` : '')
64
+ }
65
+ if (Array.isArray(response.body)) {
66
+ message += ':\n' + response.body
67
+ .map(e => `${e.type}:${e.pos.line}:${e.pos.col}: ${e.message}${e.context ? `(${e.context})` : ''}`)
68
+ .map(e => e.trim()) // TODO: remove after fixing https://github.com/aeternity/aesophia_http/issues/80
69
+ .join('\n')
70
+ }
71
+ response.statusText = message
72
+ return response
73
+ }
56
74
  })
57
75
  this.compilerVersion = client.spec.info.version
58
76
  this._compilerApi = client.api
59
77
 
60
- this._isCompiler6 = semverSatisfies(this.compilerVersion, COMPILER_6_GE_VERSION, COMPILER_LT_VERSION)
61
78
  if (ignoreVersion) return
62
79
  if (!semverSatisfies(this.compilerVersion, COMPILER_GE_VERSION, COMPILER_LT_VERSION)) {
63
80
  throw new Error(`Unsupported compiler version ${this.compilerVersion}. ` +
@@ -74,6 +91,17 @@ export default AsyncInit.compose(ContractBase, {
74
91
  this._ensureCompilerReady()
75
92
  return Promise.resolve(this.compilerVersion)
76
93
  },
94
+ /**
95
+ * Encode call data for contract call
96
+ * @function
97
+ * @category async
98
+ * @param {String} source Contract source code
99
+ * @param {String} name Name of function to call
100
+ * @param {Array} args Argument's for call
101
+ * @param {Object} [options={}] Options
102
+ * @param {Object} [options.filesystem={}] Contract external namespaces map
103
+ * @return {Promise<String>}
104
+ */
77
105
  async contractEncodeCallDataAPI (source, name, args = [], options) {
78
106
  this._ensureCompilerReady()
79
107
  const { calldata } = await this._compilerApi.encodeCalldata({
@@ -109,6 +137,20 @@ export default AsyncInit.compose(ContractBase, {
109
137
  options: this._prepareCompilerOptions(options)
110
138
  })
111
139
  },
140
+ /**
141
+ * Decode contract call result data
142
+ * @function
143
+ * @category async
144
+ * @param {String} source - source code
145
+ * @param {String } fn - function name
146
+ * @param {String} callValue - result call data
147
+ * @param {String} callResult - result status
148
+ * @param {Object} [options={}] Options
149
+ * @param {Object} [options.filesystem={}] Contract external namespaces map
150
+ * @return {Promise<String>} Result object
151
+ * @example
152
+ * const decodedData = await sdk.contractDecodeCallResultAPI(SourceCode ,'functionName', 'cb_asdasdasd...', 'ok|revert')lt
153
+ */
112
154
  contractDecodeCallResultAPI (source, fn, callValue, callResult, options) {
113
155
  this._ensureCompilerReady()
114
156
  return this._compilerApi.decodeCallResult({
@@ -145,6 +187,5 @@ export default AsyncInit.compose(ContractBase, {
145
187
  }
146
188
  })
147
189
 
148
- const COMPILER_GE_VERSION = '4.1.0'
149
- const COMPILER_6_GE_VERSION = '6.0.0'
190
+ const COMPILER_GE_VERSION = '6.0.0'
150
191
  const COMPILER_LT_VERSION = '7.0.0'
@@ -1,6 +1,5 @@
1
1
  import BigNumber from 'bignumber.js'
2
2
  import { MAX_AUTH_FUN_GAS } from '../../tx/builder/schema'
3
- import { hash } from '../../utils/crypto'
4
3
 
5
4
  export const prepareGaParams = (ins) => async (authData, authFnName) => {
6
5
  if (typeof authData !== 'object') throw new Error('AuthData must be an object')
@@ -11,12 +10,6 @@ export const prepareGaParams = (ins) => async (authData, authFnName) => {
11
10
  return { authCallData: authData.callData, gas }
12
11
  } else {
13
12
  if (!authData.source || !authData.args) throw new Error('Auth data must contain source code and arguments.')
14
- return { authCallData: await ins.contractEncodeCall(authData.source, authFnName, authData.args), gas }
13
+ return { authCallData: await ins.contractEncodeCallDataAPI(authData.source, authFnName, authData.args), gas }
15
14
  }
16
15
  }
17
-
18
- export const getContractAuthFan = (ins) => async (source, fnName) => {
19
- const { bytecode } = await ins.contractCompile(source)
20
-
21
- return { bytecode, authFun: hash(fnName) }
22
- }
@@ -22,12 +22,11 @@
22
22
  * @export GeneralizeAccount
23
23
  * @example import { GeneralizeAccount } from '@aeternity/aepp-sdk'
24
24
  */
25
- import * as R from 'ramda'
26
-
27
25
  import { ContractAPI } from '../../ae/contract'
28
26
  import { TX_TYPE } from '../../tx/builder/schema'
29
27
  import { buildTx, unpackTx } from '../../tx/builder'
30
- import { getContractAuthFan, prepareGaParams } from './helpers'
28
+ import { prepareGaParams } from './helpers'
29
+ import { hash } from '../../utils/crypto'
31
30
 
32
31
  /**
33
32
  * GeneralizeAccount Stamp
@@ -80,21 +79,24 @@ async function isGA (address) {
80
79
  * @return {Promise<Readonly<{result: *, owner: *, createdAt: Date, address, rawTx: *, transaction: *}>>}
81
80
  */
82
81
  async function createGeneralizeAccount (authFnName, source, args = [], options = {}) {
83
- const opt = R.merge(this.Ae.defaults, options)
82
+ const opt = { ...this.Ae.defaults, ...options }
84
83
  const ownerId = await this.address(opt)
85
84
 
86
85
  if (await this.isGA(ownerId)) throw new Error(`Account ${ownerId} is already GA`)
87
86
 
88
- const { authFun, bytecode } = await getContractAuthFan(this)(source, authFnName)
89
- const callData = await this.contractEncodeCall(source, 'init', args)
90
-
91
- const { tx, contractId } = await this.gaAttachTx(R.merge(opt, { ownerId, code: bytecode, callData, authFun }))
87
+ const { tx, contractId } = await this.gaAttachTx({
88
+ ...opt,
89
+ ownerId,
90
+ code: (await this.contractCompile(source)).bytecode,
91
+ callData: await this.contractEncodeCallDataAPI(source, 'init', args),
92
+ authFun: hash(authFnName)
93
+ })
92
94
 
93
- const { hash, rawTx } = await this.send(tx, opt)
95
+ const { hash: transaction, rawTx } = await this.send(tx, opt)
94
96
 
95
97
  return Object.freeze({
96
98
  owner: ownerId,
97
- transaction: hash,
99
+ transaction,
98
100
  rawTx,
99
101
  gaContractId: contractId
100
102
  })
@@ -116,7 +118,7 @@ async function createMetaTx (rawTransaction, authData, authFnName, options = {})
116
118
  if (!authData) throw new Error('authData is required')
117
119
  // Check if authData is callData or if it's an object prepare a callData from source and args
118
120
  const { authCallData, gas } = await prepareGaParams(this)(authData, authFnName)
119
- const opt = R.merge(this.Ae.defaults, options)
121
+ const opt = { ...this.Ae.defaults, ...options }
120
122
  const { abiVersion } = await this.getVmVersion(TX_TYPE.contractCall)
121
123
  const wrappedTx = wrapInEmptySignedTx(unpackTx(rawTransaction))
122
124
  const params = {
package/src/index.js CHANGED
@@ -21,7 +21,6 @@ import * as Bytes from './utils/bytes'
21
21
  import * as TxBuilder from './tx/builder'
22
22
  import * as TxBuilderHelper from './tx/builder/helpers'
23
23
  import * as SCHEMA from './tx/builder/schema'
24
- import * as ACIHelpers from './contract/aci/helpers'
25
24
  import * as ACITransformation from './contract/aci/transformation'
26
25
  import * as AmountFormatter from './utils/amount-formatter'
27
26
  import HdWallet from './utils/hd-wallet'
@@ -64,7 +63,6 @@ export {
64
63
  Bytes,
65
64
  Contract,
66
65
  ContractCompilerAPI,
67
- ACIHelpers,
68
66
  ACITransformation,
69
67
  ChainNode,
70
68
  RpcAepp,