Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@rauschma/stringio": "^1.4.0",
"axios": "^0.19.0",
"lodash": "4.17.15",
"pact-lang-api": "https://github.com/kadena-io/pact-lang-api.git#c63892c",
"pact-lang-api": "https://github.com/kadena-io/pact-lang-api.git#0ecc7f9",
"tmp": "0.1.0"
},
"devDependencies": {
Expand Down
65 changes: 54 additions & 11 deletions src/pactApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ export interface ISendOptions {
keyPair: IKeyPair
}

// The request format expected by the /local endpoint.
export interface ILocalRequest {
hash: string
sigs: {}[]
cmd: string
}

// The request format expected by the /send endpoint.
export interface ISendRequest {
cmds: {
hash: string
sigs: {}[]
cmd: string
}[]
cmds: ILocalRequest[]
}

// The response format returned by the /send endpoint.
Expand Down Expand Up @@ -53,11 +56,15 @@ export interface IListenResult {
}

// Example meta object. Currently we just send this with every transaction.
const META = {
chainId: '16',
gasPrice: 1,
gasLimit: 100000,
sender: 'someSender',
function meta() {
return {
sender: 'someSender',
chainId: '16',
gasPrice: 1,
gasLimit: 100000,
creationTime: Date.now() / 1000,
ttl: 6000, // 10 minutes
}
}

function generateNonce(): string {
Expand Down Expand Up @@ -126,7 +133,7 @@ export default class PactApi {
nonce,
code,
data,
META,
meta(),
)
}

Expand All @@ -139,6 +146,10 @@ export default class PactApi {
return this._post('/send', sendRequest)
}

async local(sendRequest: ILocalRequest): Promise<IListenResult> {
return this._post('/local', sendRequest)
}

async listen(listenRequest: IListenRequest): Promise<IListenResult> {
return this._post('/listen', listenRequest)
}
Expand All @@ -158,4 +169,36 @@ export default class PactApi {
}
return result.data!
}

/**
* Local eval for read-only operations.
*/
async evalLocal(options: ISendOptions): Promise<{}> {
const nonce = options.nonce || generateNonce()
const code: string = (options.codeFile ? await loadFile(options.codeFile) : options.code) || ''
const data: {} = (options.dataFile ? JSON.parse(await loadFile(options.dataFile)) : options.data) || {}
const keyPair = {
publicKey: options.keyPair.publicKey.toString('hex'),
secretKey: options.keyPair.privateKey.toString('hex'),
}
if (!keyPair.publicKey) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this check repeated in the non-local command eval too?

throw new Error('Public key is empty.')
} else if (!keyPair.secretKey) {
throw new Error('Private key is empty.')
}
const localRequest = pact.simple.exec.createLocalCommand(
keyPair,
nonce,
code,
data,
meta(),
)
const { result } = await this.local(localRequest)
if (result.status === 'failure') {
throw new Error(`Pact eval failed with error: ${result.error!.message} - ${result.error!.info}`)
} else if (result.status !== 'success') {
throw new Error(`Pact eval failed with unknown status: '${result.status}'`)
}
return result.data!
}
}
5 changes: 4 additions & 1 deletion src/scripts/pactRepl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import PactApi from '../pactApi'
import * as pactUtils from '../pactUtils'
import * as config from './config'

const LOCAL_MODE = '--local' in process.argv

async function prompt(message: string): Promise<string> {
const reader = readline.createInterface({
input: process.stdin,
Expand All @@ -23,11 +25,12 @@ async function prompt(message: string): Promise<string> {

async function main(): Promise<void> {
const pactApi = new PactApi(config.getUrl())
const evalFn = (LOCAL_MODE ? pactApi.eval : pactApi.evalLocal).bind(pactApi)
const adminKeyPair = config.getAdminKeyPair()

while (true) {
const line = await prompt('> ')
await pactApi.eval({
await evalFn({
code: line,
keyPair: adminKeyPair,
data: pactUtils.keysetData(adminKeyPair.publicKey, 'my-keyset'),
Expand Down
9 changes: 6 additions & 3 deletions src/scripts/runFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,21 @@
import PactApi from '../pactApi'
import * as config from './config'

const LOCAL_MODE = '--local' in process.argv

const args = process.argv.slice(2);

if (args.length !== 1) {
console.error('Usage: node runFile.js my-pact-script.pact')
if (args.length < 1 || args.length > 2) {
console.error('Usage: node runFile.js my-pact-script.pact [--local]')
process.exit(1)
}

const [codeFile] = args
const adminKeyPair = config.getAdminKeyPair()
const pactApi = new PactApi(config.getUrl())

pactApi.eval({
const evalFn = (LOCAL_MODE ? pactApi.eval : pactApi.evalLocal).bind(pactApi)
evalFn({
codeFile,
keyPair: adminKeyPair,
}).then(console.log).catch(console.error)
13 changes: 8 additions & 5 deletions src/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ declare module 'pact-lang-api' {
secretKey: string,
}

interface LocalRequest {
hash: string
sigs: {}[]
cmd: string
}

interface SendRequest {
cmds: {
hash: string
sigs: {}[]
cmd: string
}[]
cmds: LocalRequest[]
}

var crypto: {
Expand All @@ -19,6 +21,7 @@ declare module 'pact-lang-api' {
var simple: {
exec: {
createCommand: (keyPair: KeyPair, nonce: string, code: string, data: {}, meta: {}) => SendRequest
createLocalCommand: (keyPair: KeyPair, nonce: string, code: string, data: {}, meta: {}) => LocalRequest
createListenRequest: (sendRequest: SendRequest) => { requestKey: string }
}
}
Expand Down
Loading