diff --git a/es/contract/aci/transformation.js b/es/contract/aci/transformation.js index f3ab2eff01..59c9b7899a 100644 --- a/es/contract/aci/transformation.js +++ b/es/contract/aci/transformation.js @@ -94,21 +94,20 @@ export function readType (type, { bindings } = {}) { * @param bindings * @return {string} */ -export async function transform (type, value, { bindings } = {}) { +export function transform (type, value, { bindings } = {}) { const { t, generic } = readType(type, { bindings }) switch (t) { case SOPHIA_TYPES.string: return `"${value}"` case SOPHIA_TYPES.list: - return `[${await Promise.all(value.map(async el => transform(generic, el, { bindings })))}]` + return `[${value.map(el => transform(generic, el, { bindings }))}]` case SOPHIA_TYPES.tuple: - return `(${await Promise.all(value.map(async (el, i) => transform(generic[i], el, { + return `(${value.map((el, i) => transform(generic[i], el, { bindings - })))})` + }))})` case SOPHIA_TYPES.option: { - const optionV = await value.catch(e => undefined) - return optionV === undefined ? 'None' : `Some(${await transform(generic, optionV, { + return value === undefined ? 'None' : `Some(${transform(generic, value, { bindings })})` } @@ -117,10 +116,9 @@ export async function transform (type, value, { bindings } = {}) { case SOPHIA_TYPES.signature: return `#${typeof value === 'string' ? value : Buffer.from(value).toString('hex')}` case SOPHIA_TYPES.record: - return `{${await generic.reduce( - async (acc, { name, type }, i) => { - acc = await acc - acc += `${i !== 0 ? ',' : ''}${name} = ${await transform(type, value[name], { + return `{${generic.reduce( + (acc, { name, type }, i) => { + acc += `${i !== 0 ? ',' : ''}${name} = ${transform(type, value[name], { bindings })}` return acc @@ -136,18 +134,18 @@ export async function transform (type, value, { bindings } = {}) { return `${value}` } -async function transformVariant (value, generic, { bindings }) { +function transformVariant (value, generic, { bindings }) { const [[variant, variantArgs]] = typeof value === 'string' ? [[value, []]] : Object.entries(value) const [[v, type]] = Object.entries(generic.find(o => Object.keys(o)[0].toLowerCase() === variant.toLowerCase())) return `${v}${!type.length ? '' - : `(${await Promise.all(variantArgs.slice(0, type.length).map(async (el, i) => transform(type[i], el, { + : `(${variantArgs.slice(0, type.length).map((el, i) => transform(type[i], el, { bindings - })))})` + }))})` }` } -export async function transformMap (value, generic, { bindings }) { +export function transformMap (value, generic, { bindings }) { if (value instanceof Map) { value = Array.from(value.entries()) } @@ -155,14 +153,13 @@ export async function transformMap (value, generic, { bindings }) { value = Object.entries(value) } - return `{${await value + return `{${value .reduce( - async (acc, [key, value], i) => { - acc = await acc + (acc, [key, value], i) => { if (i !== 0) acc += ',' - acc += `[${await transform(generic[0], key, { + acc += `[${transform(generic[0], key, { bindings - })}] = ${await transform(generic[1], value, { bindings })}` + })}] = ${transform(generic[1], value, { bindings })}` return acc }, '' @@ -285,7 +282,7 @@ export function prepareSchema (type, { bindings } = {}) { case SOPHIA_TYPES.signature: return JoiBinary.binary().bufferCheck(64).error(getJoiErrorMsg) case SOPHIA_TYPES.option: - return Joi.object().type(Promise).error(getJoiErrorMsg) + return prepareSchema(generic, { bindings }).optional().error(getJoiErrorMsg) // @Todo Need to transform Map to Array of arrays before validating it // case SOPHIA_TYPES.map: // return Joi.array().items(Joi.array().ordered(generic.map(type => prepareSchema(type)))) @@ -373,7 +370,7 @@ export function validateArguments (aci, params) { const validationSchema = Joi.array().ordered( aci.arguments .map(({ type }, i) => prepareSchema(type, { bindings: aci.bindings }).label(`[${params[i]}]`)) - ).label('Argument') + ).sparse(true).label('Argument') const { error } = Joi.validate(params, validationSchema, { abortEarly: false }) if (error) { throw error diff --git a/test/integration/contract.js b/test/integration/contract.js index d560b921e8..597af62075 100644 --- a/test/integration/contract.js +++ b/test/integration/contract.js @@ -226,14 +226,14 @@ describe('Contract', function () { isCompiled.should.be.equal(true) }) it('Dry-run deploy fn', async () => { - const res = await contractObject.methods.init.get('123', 1, Promise.resolve('hahahaha')) + const res = await contractObject.methods.init.get('123', 1, 'hahahaha') res.result.should.have.property('gasUsed') res.result.should.have.property('returnType') }) it('Dry-run deploy fn on specific account', async () => { const current = await contract.address() const onAccount = contract.addresses().find(acc => acc !== current) - const { result } = await contractObject.methods.init.get('123', 1, Promise.resolve('hahahaha'), { onAccount }) + const { result } = await contractObject.methods.init.get('123', 1, 'hahahaha', { onAccount }) result.should.have.property('gasUsed') result.should.have.property('returnType') result.callerId.should.be.equal(onAccount) @@ -241,7 +241,7 @@ describe('Contract', function () { it('Deploy contract before compile', async () => { contractObject.compiled = null - await contractObject.methods.init('123', 1, Promise.resolve('hahahaha')) + await contractObject.methods.init('123', 1, 'hahahaha') const isCompiled = contractObject.compiled.length && contractObject.compiled.slice(0, 3) === 'cb_' isCompiled.should.be.equal(true) }) @@ -383,22 +383,22 @@ describe('Contract', function () { }) it('Map With Option Value', async () => { const address = await contract.address() - let mapArgWithSomeValue = new Map( + const mapArgWithSomeValue = new Map( [ - [address, ['someStringV', Promise.resolve(123)]] + [address, ['someStringV', 123]] ] ) - let mapArgWithNoneValue = new Map( + const mapArgWithNoneValue = new Map( [ - [address, ['someStringV', Promise.reject(Error()).catch(e => undefined)]] + [address, ['someStringV', undefined]] ] ) - let returnArgWithSomeValue = new Map( + const returnArgWithSomeValue = new Map( [ [address, ['someStringV', 123]] ] ) - let returnArgWithNoneValue = new Map( + const returnArgWithNoneValue = new Map( [ [address, ['someStringV', undefined]] ] @@ -435,7 +435,7 @@ describe('Contract', function () { describe('RECORD/STATE', function () { const objEq = (obj, obj2) => !Object.entries(obj).find(([key, val]) => JSON.stringify(obj2[key]) !== JSON.stringify(val)) it('Valid Set Record (Cast from JS object)', async () => { - await contractObject.methods.setRecord({ value: 'qwe', key: 1234, testOption: Promise.resolve('test') }) + await contractObject.methods.setRecord({ value: 'qwe', key: 1234, testOption: 'test' }) const state = await contractObject.methods.getRecord() objEq(state.decodedResult, { value: 'qwe', key: 1234, testOption: 'test' }).should.be.equal(true) @@ -445,7 +445,7 @@ describe('Contract', function () { objEq(result.decodedResult, { value: 'qwe', key: 1234, testOption: 'test' }).should.be.equal(true) }) it('Get Record With Option (Convert to JS object)', async () => { - await contractObject.methods.setRecord({ key: 1234, value: 'qwe', testOption: Promise.resolve('resolved string') }) + await contractObject.methods.setRecord({ key: 1234, value: 'qwe', testOption: 'resolved string' }) const result = await contractObject.methods.getRecord() objEq(result.decodedResult, { value: 'qwe', key: 1234, testOption: 'resolved string' }).should.be.equal(true) }) @@ -459,25 +459,25 @@ describe('Contract', function () { }) describe('OPTION', function () { it('Set Some Option Value(Cast from JS value/Convert result to JS)', async () => { - const optionRes = await contractObject.methods.intOption(Promise.resolve(123)) + const optionRes = await contractObject.methods.intOption(123) optionRes.decodedResult.should.be.equal(123) }) it('Set Some Option List Value(Cast from JS value/Convert result to JS)', async () => { - const optionRes = await contractObject.methods.listOption(Promise.resolve([[1, 'testString']])) + const optionRes = await contractObject.methods.listOption([[1, 'testString']]) JSON.stringify(optionRes.decodedResult).should.be.equal(JSON.stringify([[1, 'testString']])) }) it('Set None Option Value(Cast from JS value/Convert to JS)', async () => { - const optionRes = await contractObject.methods.intOption(Promise.reject(Error())) + const optionRes = await contractObject.methods.intOption(undefined) const isUndefined = optionRes.decodedResult === undefined isUndefined.should.be.equal(true) }) it('Invalid option type', async () => { try { - await contractObject.methods.intOption({ s: 2 }) + await contractObject.methods.intOption('string') } catch (e) { - e.message.should.be.equal('"Argument" at position 0 fails because [Value \'[[object Object]]\' at path: [0] not a Promise]') + e.message.should.be.equal('"Argument" at position 0 fails because [Value "[string]" at path: [0] not a number]') } }) })