Skip to content

Commit

Permalink
refactor(compiler): use swagger file
Browse files Browse the repository at this point in the history
  • Loading branch information
davidyuk committed Apr 28, 2021
1 parent 8ff5afe commit 0d82161
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 228 deletions.
13 changes: 0 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
"@stamp/it": "^1.0.3",
"@stamp/required": "^1.0.1",
"aes-js": "^3.1.1",
"axios": "^0.21.1",
"bignumber.js": "^9.0.0",
"bip32-path": "^0.4.2",
"blakejs": "^1.1.0",
Expand Down
4 changes: 2 additions & 2 deletions src/contract/aci/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ export function getFunctionACI (aci, name, { external }) {
bindings: [
{
state: aci.state,
type_defs: aci.type_defs,
typeDefs: aci.typeDefs,
name: aci.name
},
...external.map(R.pick(['state', 'type_defs', 'name']))
...external.map(R.pick(['state', 'typeDefs', 'name']))
],
event: aci.event ? aci.event.variant : []
}
Expand Down
4 changes: 2 additions & 2 deletions src/contract/aci/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ export default async function getContractInstance (source, { aci, contractAddres
}
const instance = {
interface: R.defaultTo(null, R.prop('interface', aci)),
aci: R.defaultTo(null, R.path(['encoded_aci', 'contract'], aci)),
externalAci: aci.external_encoded_aci ? aci.external_encoded_aci.map(a => a.contract || a.namespace) : [],
aci: R.defaultTo(null, R.path(['encodedAci', 'contract'], aci)),
externalAci: aci.externalEncodedAci ? aci.externalEncodedAci.map(a => a.contract || a.namespace) : [],
source,
compiled: null,
deployInfo: { address: contractAddress },
Expand Down
2 changes: 1 addition & 1 deletion src/contract/aci/transformation.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export function linkTypeDefs (t, bindings) {
const [root, typeDef] = typeof t === 'object' ? Object.keys(t)[0].split('.') : t.split('.')
const contractTypeDefs = bindings.find(c => c.name === root)
const aciType = [
...contractTypeDefs.type_defs,
...contractTypeDefs.typeDefs,
{ name: 'state', typedef: contractTypeDefs.state, vars: [] }
].find(({ name }) => name === typeDef)
if (aciType.vars.length) {
Expand Down
214 changes: 100 additions & 114 deletions src/contract/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,103 +24,12 @@
* @example import { ContractCompilerAPI } from '@aeternity/aepp-sdk'
*/

import Http from '../utils/http'
import ContractBase from './index'
import semverSatisfies from '../utils/semver-satisfies'
import AsyncInit from '../utils/async-init'
import genSwaggerClient from '../utils/swagger'
import { VM_TYPE } from '../tx/builder/schema'

async function getCompilerVersion (options = {}) {
return this.http
.get('/api-version', options)
.then((res) => res['api-version'])
}

async function contractEncodeCallDataAPI (source, name, args = [], options = {}) {
this.isInit()
return this.http
.post('/encode-calldata', { source, function: name, arguments: args, options: this.prepareCompilerOption(options) }, options)
.then(({ calldata }) => calldata)
}

async function contractDecodeCallDataByCodeAPI (bytecode, calldata, backend = this.compilerOptions.backend, options = {}) {
this.isInit()
return this.http
.post('/decode-calldata/bytecode', { bytecode, calldata, backend }, options)
}

async function contractDecodeCallDataBySourceAPI (source, fn, callData, options = {}) {
this.isInit()
return this.http
.post('/decode-calldata/source', { function: fn, source, calldata: callData, options: this.prepareCompilerOption(options) }, options)
}

async function contractDecodeCallResultAPI (source, fn, callValue, callResult, options = {}) {
this.isInit()
return this.http
.post('/decode-call-result', { function: fn, source, 'call-result': callResult, 'call-value': callValue, options: this.prepareCompilerOption(options) }, options)
}

async function contractDecodeDataAPI (type, data, options = {}) {
this.isInit()
return this.http
.post('/decode-data', { data, 'sophia-type': type }, options)
.then(({ data }) => data)
}

async function validateByteCodeAPI (bytecode, source, options = {}) {
this.isInit()
return this.http
.post('/validate-byte-code', { bytecode, source, options: this.prepareCompilerOption(options) }, options)
.then(res => typeof res === 'object' ? true : res)
}

async function compileContractAPI (code, options = {}) {
this.isInit()
return this.http.post('/compile', { code, options: this.prepareCompilerOption(options) }, options)
.then(({ bytecode }) => bytecode)
}

async function contractGetACI (code, options = {}) {
this.isInit()
return this.http.post('/aci', { code, options: this.prepareCompilerOption(options) }, options)
}

async function getFateAssembler (bytecode, options = {}) {
this.isInit()
return this.http.post('/fate-assembler', { bytecode, options: this.prepareCompilerOption(options) }, options)
}

async function getBytecodeCompilerVersion (bytecode, options = {}) {
this.isInit()
return this.http.post('/compiler-version', { bytecode, options: this.prepareCompilerOption(options) }, options)
}

async function setCompilerUrl (url, { ignoreVersion = false } = {}) {
this.http.changeBaseUrl(url)
this.compilerVersion = await this.getCompilerVersion().catch(e => null)
await this.checkCompatibility({ ignoreVersion })
}

async function checkCompatibility ({ force = false, ignoreVersion = false } = {}) {
if (!this.compilerVersion && !force) throw new Error('Compiler do not respond')
if (!ignoreVersion && this.compilerVersion && !semverSatisfies(this.compilerVersion, COMPILER_GE_VERSION, COMPILER_LT_VERSION)) {
const version = this.compilerVersion
this.compilerVersion = null
throw new Error(`Unsupported compiler version ${version}. ` +
`Supported: >= ${COMPILER_GE_VERSION} < ${COMPILER_LT_VERSION}`)
}
}

function prepareCompilerOption ({ backend = this.compilerOptions.backend, filesystem = {} } = {}) {
return { backend, file_system: filesystem }
}

function isInit () {
if (this.compilerVersion === null) throw new Error('Compiler not defined')
return true
}

/**
* Contract Compiler Stamp
*
Expand All @@ -133,28 +42,107 @@ function isInit () {
* @return {Object} Contract compiler instance
* @example ContractCompilerAPI({ compilerUrl: 'COMPILER_URL' })
*/
const ContractCompilerAPI = AsyncInit.compose(ContractBase, {
async init ({ compilerUrl = this.compilerUrl, ignoreVersion = false }) {
this.http = Http({ baseUrl: compilerUrl })
this.compilerVersion = await this.getCompilerVersion().catch(e => null)
await this.checkCompatibility({ force: true, ignoreVersion })
export default AsyncInit.compose(ContractBase, {
async init ({ compilerUrl, ignoreVersion }) {
if (!compilerUrl) return
await this.setCompilerUrl(compilerUrl, { ignoreVersion })
},
methods: {
contractEncodeCallDataAPI,
contractDecodeDataAPI,
compileContractAPI,
contractGetACI,
contractDecodeCallDataByCodeAPI,
contractDecodeCallDataBySourceAPI,
contractDecodeCallResultAPI,
setCompilerUrl,
getCompilerVersion,
validateByteCodeAPI,
isInit,
checkCompatibility,
prepareCompilerOption,
getFateAssembler,
getBytecodeCompilerVersion
async setCompilerUrl (compilerUrl, { ignoreVersion = false } = {}) {
if (!compilerUrl) throw new Error('"compilerUrl" required')
compilerUrl = compilerUrl.replace(/\/$/, '')
const client = await genSwaggerClient(`${compilerUrl}/api`, {
disableBigNumbers: true,
keysOfValuesToIgnore: ['fileSystem', 'arguments']
})
this.compilerVersion = client.spec.info.version
this._compilerApi = client.api

if (ignoreVersion) return
if (!semverSatisfies(this.compilerVersion, COMPILER_GE_VERSION, COMPILER_LT_VERSION)) {
throw new Error(`Unsupported compiler version ${this.compilerVersion}. ` +
`Supported: >= ${COMPILER_GE_VERSION} < ${COMPILER_LT_VERSION}`)
}
},
_ensureCompilerReady () {
if (!this._compilerApi) throw new Error('Compiler is not ready')
},
_prepareCompilerOptions ({ backend = this.compilerOptions.backend, filesystem = {} } = {}) {
return { backend, fileSystem: filesystem }
},
getCompilerVersion () {
this._ensureCompilerReady()
return Promise.resolve(this.compilerVersion)
},
async contractEncodeCallDataAPI (source, name, args = [], options) {
this._ensureCompilerReady()
const { calldata } = await this._compilerApi.encodeCalldata({
source,
function: name,
arguments: args,
options: this._prepareCompilerOptions(options)
})
return calldata
},
async contractDecodeDataAPI (type, data) {
this._ensureCompilerReady()
return (await this._compilerApi.decodeData({ data, 'sophia-type': type })).data
},
async compileContractAPI (code, options) {
this._ensureCompilerReady()
const { bytecode } = await this._compilerApi.compileContract({
code,
options: this._prepareCompilerOptions(options)
})
return bytecode
},
contractGetACI (code, options) {
this._ensureCompilerReady()
return this._compilerApi.generateACI({ code, options: this._prepareCompilerOptions(options) })
},
contractDecodeCallDataByCodeAPI (bytecode, calldata, backend = this.compilerOptions.backend) {
this._ensureCompilerReady()
return this._compilerApi.decodeCalldataBytecode({ bytecode, calldata, backend })
},
contractDecodeCallDataBySourceAPI (source, fn, callData, options) {
this._ensureCompilerReady()
return this._compilerApi.decodeCalldataSource({
function: fn,
source,
calldata: callData,
options: this._prepareCompilerOptions(options)
})
},
contractDecodeCallResultAPI (source, fn, callValue, callResult, options) {
this._ensureCompilerReady()
return this._compilerApi.decodeCallResult({
function: fn,
source,
'call-result': callResult,
'call-value': callValue,
options: this._prepareCompilerOptions(options)
})
},
async validateByteCodeAPI (bytecode, source, options) {
this._ensureCompilerReady()
const res = await this._compilerApi.validateByteCode({
bytecode,
source,
options: this._prepareCompilerOptions(options)
})
return typeof res === 'object' ? true : res
},
getFateAssembler (bytecode, options) {
this._ensureCompilerReady()
return this._compilerApi.getFateAssemblerCode({ bytecode, options: this._prepareCompilerOptions(options) })
},
getBytecodeCompilerVersion (bytecode, options) {
this._ensureCompilerReady()
return this._compilerApi.getCompilerVersion({
bytecode,
options: this._prepareCompilerOptions(options)
})
}
},
props: {
compilerVersion: null,
Expand All @@ -166,5 +154,3 @@ const ContractCompilerAPI = AsyncInit.compose(ContractBase, {

const COMPILER_GE_VERSION = '4.1.0'
const COMPILER_LT_VERSION = '5.0.0'

export default ContractCompilerAPI
2 changes: 1 addition & 1 deletion src/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const Node = AsyncInit.compose({
if (!url) throw new Error('"url" required')
this.url = url.replace(/\/$/, '')
this.internalUrl = internalUrl ? internalUrl.replace(/\/$/, '') : this.url
const client = await genSwaggerClient(`${this.url}/api`, this.internalUrl)
const client = await genSwaggerClient(`${this.url}/api`, { internalUrl: this.internalUrl })
this.version = client.spec.info.version
this.api = client.api
},
Expand Down
71 changes: 0 additions & 71 deletions src/utils/http.js

This file was deleted.

Loading

0 comments on commit 0d82161

Please sign in to comment.