Skip to content

Commit d7dd470

Browse files
committed
0.1.5
1 parent a5eac4f commit d7dd470

File tree

8 files changed

+3878
-3349
lines changed

8 files changed

+3878
-3349
lines changed

package-lock.json

Lines changed: 3788 additions & 3209 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@execution-machine/sdk",
3-
"version": "0.1.42",
3+
"version": "0.1.5",
44
"description": "",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -25,7 +25,8 @@
2525
"homepage": "https://github.com/exmbuild/exm-js-sdk#readme",
2626
"dependencies": {
2727
"@types/node": "^18.0.0",
28-
"arweave": "^1.11.4",
28+
"chalk": "^4.1.2",
29+
"cli-box": "^6.0.10",
2930
"commander": "^9.3.0",
3031
"dotenv": "^16.0.1",
3132
"find-cache-dir": "^3.3.2",
@@ -34,7 +35,8 @@
3435
"three-em-0-3-09": "npm:@three-em/node@^0.3.09",
3536
"three-em-0-3-12": "npm:@three-em/node@^0.3.12",
3637
"three-em-0-3-13": "npm:@three-em/node@^0.3.13",
37-
"three-em-0-3-14": "npm:@three-em/node@^0.3.14"
38+
"three-em-0-3-14": "npm:@three-em/node@^0.3.14",
39+
"three-em-0-3-15": "npm:@three-em/node@^0.3.15"
3840
},
3941
"devDependencies": {
4042
"@types/jest": "^29.1.0",

src/cli/cmd/functions/deploy.ts

Lines changed: 64 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,24 @@
11
import {readFileSync} from "fs";
22
import {DeployOpts} from "./model";
3-
import {TextDecoder, TextEncoder} from "util";
43
import {ContractType, Tag} from "../../../common/model";
54
import {em} from "../em-wrapper";
65
import {error} from "../../utils/common";
76
import {figureOutContractType} from "../../../common/utils/commons";
87

9-
const Arweave = require('arweave');
10-
const Confirm = require('prompt-confirm');
11-
12-
const Encoder = new TextEncoder();
13-
const Decoder = new TextDecoder();
14-
15-
const initContract = async (initState: string, contractTxId: string, wallet: any, arweave: typeof Arweave) => {
16-
const tx = await arweave.createTransaction({
17-
data: Encoder.encode(initState),
18-
});
19-
20-
tx.addTag("Contract-Src", contractTxId);
21-
await arweave.transactions.sign(tx, wallet);
228

23-
return [tx, {
24-
id: tx.id,
25-
tags: tx.tags.map(({ name, value }: Tag) => ({
26-
name: atob(name),
27-
value: atob(value),
28-
})),
29-
data: Decoder.decode(tx.data),
30-
}];
31-
}
32-
33-
const successfulDeployment = (sourceTxId: string, initTxId: string) => {
34-
console.log("Function deployed 🎉\n");
35-
console.log(`EXM Function ID: ${initTxId}`);
36-
console.log("EXM Function Source Code:", "https://arweave.net/tx/" + sourceTxId);
37-
console.log("EXM Function:", "https://arweave.net/tx/" + initTxId);
38-
console.log(`\nUse Function Id ${initTxId} as your interaction reference.`);
39-
}
9+
const Confirm = require('prompt-confirm');
10+
const chalk = require('chalk');
11+
12+
const boxMarks = {
13+
nw: '╭',
14+
n: '─',
15+
ne: '╮',
16+
e: '│',
17+
se: '╯',
18+
s: '─',
19+
sw: '╰',
20+
w: '│'
21+
};
4022

4123
export const functionDeployCmd = async (opts: DeployOpts) => {
4224
let contentType: ContractType = figureOutContractType(opts.type || opts.src, opts.type !== undefined);
@@ -50,113 +32,65 @@ export const functionDeployCmd = async (opts: DeployOpts) => {
5032
error(`Deployment requires --init-state or --init-state-src to be passed`);
5133
}
5234

53-
if(opts.useArweave === true) {
54-
const arweave = Arweave.init({
55-
host: "arweave.net",
56-
port: 443,
57-
protocol: "https",
58-
});
59-
60-
if (!opts.wallet) {
61-
error('--wallet (Wallet Path) is required for deployments');
62-
}
63-
64-
const wallet = JSON.parse(readFileSync(opts.wallet, 'utf8'));
65-
const address: string = await arweave.wallets.jwkToAddress(wallet);
66-
console.log("Deploying function using wallet", address);
67-
68-
if (opts.contractTx) {
69-
console.log("Deploying contract using source transaction", opts.contractTx);
70-
71-
const initDeploymentTx = await initContract(initState, opts.contractTx, wallet, arweave);
72-
console.log("\nInit Function:", initDeploymentTx[1]);
73-
74-
const doDeploy = await new Confirm('Do you want to deploy this function?').run();
75-
76-
if (doDeploy) {
77-
const res = await arweave.transactions.post(initDeploymentTx[0]);
78-
if (res.status >= 400) {
79-
error(`Failed to deploy init Function. Source Function ID: ${opts.contractTx}`);
80-
}
35+
let contractData: Uint8Array;
8136

82-
successfulDeployment(opts.contractTx, initDeploymentTx[1].id);
83-
} else {
84-
console.log("\nDeployment cancelled");
85-
}
86-
} else if (opts.src) {
87-
// Source Contract
88-
const txSource = await arweave.createTransaction({
89-
data: readFileSync(opts.src),
90-
});
91-
txSource.addTag("Content-Type", contentType);
92-
txSource.addTag("App-Name", "EM");
93-
txSource.addTag("Type", "Serverless-Function");
94-
await arweave.transactions.sign(txSource, wallet);
95-
96-
// Init Contract
97-
const txInit = await initContract(initState, txSource.id, wallet, arweave);
98-
99-
console.log(`\nSource Contract:`, {
100-
id: txSource.id,
101-
tags: txSource.tags.map(({name, value}: { [x: string]: string }) => ({
102-
name: atob(name),
103-
value: atob(value),
104-
}))
105-
});
106-
107-
console.log(`\nInit Contract`, txInit[1]);
108-
109-
const confirmation = await new Confirm('Do you want to deploy this function?').run();
110-
111-
if (confirmation) {
112-
const txSourceDeployment = await arweave.transactions.post(txSource);
113-
if (txSourceDeployment.status >= 400) {
114-
error(`Failed to deploy source contract.`);
115-
} else {
116-
const initContractDeployment = await arweave.transactions.post(txInit[0]);
117-
if (initContractDeployment.status >= 400) {
118-
error(`Failed to init function. Source function ID: ${txSource.id}`);
119-
}
120-
}
37+
if(!opts.token) {
38+
error('EXM Token (--token) is required to deploy functions through EXM');
39+
}
12140

122-
successfulDeployment(txSource.id, txInit[1].id);
123-
} else {
124-
console.log("\nDeployment cancelled");
125-
}
41+
if(opts.contractTx) {
42+
const fetchContractSourceTx = await fetch(`https://arweave.net/${opts.contractTx}`);
43+
if(fetchContractSourceTx.ok) {
44+
contractData = new Uint8Array(await fetchContractSourceTx.arrayBuffer());
12645
} else {
127-
error(`Deployment requires --contract-tx or --src`);
46+
console.error(`Source function transaction ${opts.contractTx} is invalid or does not exist.`);
12847
}
48+
} else if(opts.src) {
49+
contractData = await readFileSync(opts.src);
12950
} else {
130-
let contractData: Uint8Array;
51+
error(`Deployment requires --contract-tx or --src`);
52+
}
13153

132-
if(!opts.token) {
133-
error('EXM Token (--token) is required to deploy functions through EXM');
134-
}
54+
const confirmation = await new Confirm(`Do you want to deploy this function?`).run();
55+
if(confirmation) {
13556

136-
if(opts.contractTx) {
137-
const fetchContractSourceTx = await fetch(`https://arweave.net/${opts.contractTx}`);
138-
if(fetchContractSourceTx.ok) {
139-
contractData = new Uint8Array(await fetchContractSourceTx.arrayBuffer());
140-
} else {
141-
console.error(`Source function transaction ${opts.contractTx} is invalid or does not exist.`);
142-
}
143-
} else if(opts.src) {
144-
contractData = await readFileSync(opts.src);
145-
} else {
146-
error(`Deployment requires --contract-tx or --src`);
57+
if(opts.token) {
58+
em.changeToken(opts.token);
14759
}
14860

149-
const confirmation = await new Confirm(`Do you want to deploy this function?`).run();
150-
if(confirmation) {
151-
152-
if(opts.token) {
153-
em.changeToken(opts.token);
154-
}
155-
156-
const beginDeployment = await em.functions.deploy(contractData, initState, contentType);
157-
console.log(`Function deployed 🎉\n`);
158-
console.log(`EXM Function ID: ${beginDeployment.id}`);
159-
console.log(`EXM Function: https://arweave.net/${beginDeployment.id}`);
160-
}
61+
const Box = require('cli-box');
62+
const beginDeployment = await em.functions.deploy(contractData, initState, contentType);
63+
64+
const resultBox = new Box({
65+
w: 100,
66+
h: 4,
67+
stringify: false,
68+
marks: boxMarks,
69+
hAlign: 'left',
70+
vAlign: 'top'
71+
}, `Function deployed 🎉
72+
▸ EXM Function ID : ${beginDeployment.id}
73+
▸ EXM Function Source : https://arweave.net/${beginDeployment.id}
74+
▸ Function URL : https://${beginDeployment.id}.exm.run`);
75+
76+
console.log(resultBox.stringify());
77+
78+
const functionUrlExample = new Box({
79+
w: 100,
80+
h: 8,
81+
stringify: false,
82+
marks: boxMarks,
83+
hAlign: 'left',
84+
vAlign: 'top'
85+
}, `${chalk.blue('Id: ')} ${beginDeployment.id}
86+
87+
curl --location --request POST 'https://${beginDeployment.id}.exm.run'
88+
--header 'Content-Type: application/json'
89+
--data-raw '{}' ${chalk.blue('<= Any JSON body')}
90+
91+
Documentation: https://docs.exm.dev/trustless-serverless-functions/function-urls
92+
`);
93+
94+
console.log(functionUrlExample.stringify());
16195
}
16296
}

src/cli/cmd/functions/evaluate/app-simulator.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SimulateExecutionContext } from "three-em-0-3-14";
1+
import {simulateContract, SimulateExecutionContext} from "three-em-0-3-15";
22

33
export interface ExmRunContext extends SimulateExecutionContext {
44
version: string;
@@ -19,6 +19,9 @@ export const runExmFunction = (context: ExmRunContext) => {
1919
} else if(isVersion(context.version)('0.3.14')) {
2020
const simulateContract = require('three-em-0-3-14').simulateContract;
2121
return simulateContract(context);
22+
} else if(isVersion(context.version)('0.3.15')) {
23+
const simulateContract = require('three-em-0-3-15').simulateContract;
24+
return simulateContract(context);
2225
} else {
2326
const simulateContract = require('three-em-0-3-09').simulateContract;
2427
return simulateContract(context.contractId, context.interactions, context.contractInitState, context.maybeConfig, context.maybeCache, context.maybeBundledContract, context.maybeSettings, context.maybeExmContext);

src/cli/cmd/functions/function-test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {readFileSync} from "fs";
44
import {figureOutContractType} from "../../../common/utils/commons";
55
import {createWrite, TestFunction} from "../../../test/test-function";
66
import {ContractType} from "../../../common/model";
7-
import {SimulateContractType} from "three-em-0-3-14";
7+
import {SimulateContractType} from "three-em-0-3-15";
88

99
export const functionTest = async (opts: FunctionTestOpts) => {
1010
if(!opts.src) {

src/cli/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const program = new Command();
99

1010
program.name('exm')
1111
.description('A CLI to interact with the Execution Machine.')
12-
.version('0.1.0');
12+
.version('0.1.5');
1313

1414
program.command('function:read')
1515
.alias('fx:r')
@@ -30,14 +30,12 @@ program.command('function:write')
3030
program.command('function:deploy')
3131
.alias('fx:d')
3232
.description('Deploy a EXM compatible function to Arweave.')
33-
.option('-w, --wallet <value>', 'Path to wallet to be used during deployment.')
3433
.option('-s, --src <value>', 'Path to source code of function. Example: /Documents/function.wasm .')
3534
.option('--contract-tx <value>', 'ID of Source Function already deployed to Arweave.')
3635
.option('-i, --init-state <value>', 'Init State for Function to be deployed under init function.')
3736
.option('--init-state-src <value>', 'Path to init state file.')
3837
.option('-t, --type <value>', 'Type of function to be deployed.')
3938
.option('-t, --token <value>', 'Execution Machine API Token to be used.')
40-
.option('--use-arweave', 'Deploy function through Arweave and not EXM')
4139
.action(functionDeployCmd);
4240

4341
program.command('function:evaluate')

src/test/test-function.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {ExecuteConfig, simulateContract, SimulateContractType as ContractType, SimulateInput, Tag} from "three-em-0-3-14";
1+
import {ExecuteConfig, simulateContract, SimulateContractType as ContractType, SimulateInput, Tag} from "three-em-0-3-15";
22
import {guidGenerator} from "../common/utils/commons";
33

44
// @ts-ignore
@@ -10,7 +10,7 @@ export type ExecutionConfig = ExecuteConfig;
1010

1111
export interface TestFunctionOpts {
1212
functionSource: Uint8Array,
13-
functionType: FunctionType,
13+
functionType: ContractType,
1414
functionInitState: any;
1515
writes: WriteInput[];
1616
gatewayConfig?: ExecutionConfig

tests/cli-function.tests.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import {functionTest} from "../src/cli/cmd/functions/function-test";
2+
import {TestFunction, FunctionType, createWrite} from "../src";
3+
import {readFileSync} from "fs";
24

35
describe('CLI Functions module', () => {
46

@@ -43,4 +45,15 @@ describe('CLI Functions module', () => {
4345
});
4446
});
4547

48+
test('Function from import', async () => {
49+
const testUserRegistry = TestFunction({
50+
functionSource: readFileSync("./tests/testdata/user-registry.js"),
51+
functionType: FunctionType.JAVASCRIPT,
52+
functionInitState: {
53+
users: []
54+
},
55+
writes: [createWrite({ username: "Andres" })]
56+
})
57+
})
58+
4659
});

0 commit comments

Comments
 (0)