Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sdk): Add AssemblyScript SDK #10

Merged
merged 2 commits into from
Aug 23, 2023
Merged
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
3 changes: 2 additions & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
ARG VARIANT=18
FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:${VARIANT}
RUN apt-get update
RUN apt-get -y install --no-install-recommends zsh
RUN apt-get -y install --no-install-recommends zsh
RUN apt-get -y install binaryen build-essential cmake
3 changes: 3 additions & 0 deletions libs/as-sdk-integration-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# AssemblyScript Integration Tests

This project is for testing the SDK together with the VM project. This is used internally to validate if the functions act like they are supposed to
23 changes: 23 additions & 0 deletions libs/as-sdk-integration-tests/asconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"extends": "../../node_modules/@assemblyscript/wasi-shim/asconfig.json",
"targets": {
"debug": {
"outFile": "../../dist/libs/as-sdk-integration-tests/debug.wasm",
"textFile": "../../dist/libs/as-sdk-integration-tests/debug.wat",
"sourceMap": true,
"debug": true
},
"release": {
"outFile": "../../dist/libs/as-sdk-integration-tests/release.wasm",
"textFile": "../../dist/libs/as-sdk-integration-tests/release.wat",
"sourceMap": false,
"optimizeLevel": 3,
"shrinkLevel": 2,
"converge": true,
"noAssert": true
}
},
"options": {
"bindings": "esm"
}
}
40 changes: 40 additions & 0 deletions libs/as-sdk-integration-tests/assembly/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { httpFetch, Process } from '../../as-sdk/assembly/index';
import { testInvalidUint8JsonArray, testValidUint8JsonArray } from './json-utils-test';

const args = Process.args()[0];

if (args === 'testHttpRejection') {
testHttpRejection();
} else if (args === 'testHttpSuccess') {
testHttpSuccess();
} else if (args === 'testValidUint8JsonArray') {
testValidUint8JsonArray();
} else if (args === 'testInvalidUint8JsonArray') {
testInvalidUint8JsonArray();
}

export function testHttpRejection(): void {
const response = httpFetch('example.com/');
const rejected = response.rejected;

if (rejected !== null) {
const msg = String.UTF8.encode('rejected');
const buffer = Uint8Array.wrap(msg);

Process.exit_with_result(0, buffer);
}
}

export function testHttpSuccess(): void {
const response = httpFetch('http://example.com/');
const fulfilled = response.fulfilled;

if (fulfilled !== null) {
const msg = String.UTF8.encode('ok');
const buffer = Uint8Array.wrap(msg);

Process.exit_with_result(0, buffer);
}
}


26 changes: 26 additions & 0 deletions libs/as-sdk-integration-tests/assembly/json-utils-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { jsonArrToUint8Array, JSON, testutils } from '../../as-sdk/assembly/index';

export function testValidUint8JsonArray(): void {
const raw: string = "[0, 23, 254, 88]";
const json = <JSON.Arr>JSON.parse(raw);
const result = jsonArrToUint8Array(json);

const expected = new Uint8Array(4);
expected.set([0, 23, 254, 88]);

testutils.assert(result.byteLength === expected.byteLength, "bytelength is not equal");
testutils.assert(
String.UTF8.decode(result.buffer) === String.UTF8.decode(expected.buffer),
'buffers are not equal'
);

testutils.ok();
}

export function testInvalidUint8JsonArray(): void {
const raw: string = '[0, 23, 299, 88]';
const json = <JSON.Arr>JSON.parse(raw);
jsonArrToUint8Array(json);

testutils.error("Test should fail");
}
4 changes: 4 additions & 0 deletions libs/as-sdk-integration-tests/assembly/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../../../node_modules/assemblyscript/std/assembly.json",
"include": ["./**/*.ts"]
}
6 changes: 6 additions & 0 deletions libs/as-sdk-integration-tests/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* eslint-disable */
export default {
displayName: 'vm',
preset: '../../jest.preset.mjs',
coverageDirectory: '../../coverage/libs/as-sdk-integration-tests',
};
4 changes: 4 additions & 0 deletions libs/as-sdk-integration-tests/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@seda/as-sdk-integration-tests",
"type": "module"
}
31 changes: 31 additions & 0 deletions libs/as-sdk-integration-tests/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "as-sdk-integration-tests",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/as-sdk-integration-tests/assembly",
"projectType": "library",
"targets": {
"build": {
"executor": "nx:run-commands",
"options": {
"command": "asc ./assembly/index.ts --target debug",
"cwd": "libs/as-sdk-integration-tests"
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/as-sdk-integration-tests/jest.config.ts",
"passWithNoTests": true
},
"dependsOn": [{ "target": "build" }],
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
}
},
"tags": []
}
51 changes: 51 additions & 0 deletions libs/as-sdk-integration-tests/src/http.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { callVm, } from '../../../dist/libs/vm';
import { jest } from '@jest/globals';
import { readFile } from 'node:fs/promises';
import { HttpFetchResponse } from '../../../dist/libs/vm/src/types/vm-actions';
import { PromiseStatus } from '../../../dist/libs/vm/src/types/vm-promise';

const mockHttpFetch = jest.fn();

const TestVmAdapter = jest.fn().mockImplementation(() => {
return { httpFetch: mockHttpFetch };
});

describe('Http', () => {
it('Test SDK HTTP Rejection', async () => {

const wasmBinary = await readFile('dist/libs/as-sdk-integration-tests/debug.wasm');
const result = await callVm({
args: ['testHttpRejection'],
envs: {},
binary: new Uint8Array(wasmBinary),
});

expect(result.exitCode).toBe(0);
expect(result.result).toEqual(new TextEncoder().encode("rejected"));
});

it('Test SDK HTTP Success', async () => {
const wasmBinary = await readFile(
'dist/libs/as-sdk-integration-tests/debug.wasm'
);

const mockResponse = new HttpFetchResponse({
content_length: 1,
bytes: [1],
headers: {},
status: 200,
url: 'http://example.com',
});

mockHttpFetch.mockResolvedValue(PromiseStatus.fulfilled(mockResponse));

const result = await callVm({
args: ['testHttpSuccess'],
envs: {},
binary: new Uint8Array(wasmBinary),
}, undefined, new TestVmAdapter());

expect(result.exitCode).toBe(0);
expect(result.result).toEqual(new TextEncoder().encode('ok'));
});
});
32 changes: 32 additions & 0 deletions libs/as-sdk-integration-tests/src/jsonutils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { readFile } from "fs/promises";
import { callVm } from "../../../dist/libs/vm/src";

describe('json-utils', () => {
it('should handle valid u8 json arrays', async () => {
const wasmBinary = await readFile(
'dist/libs/as-sdk-integration-tests/debug.wasm'
);
const result = await callVm({
args: ['testValidUint8JsonArray'],
envs: {},
binary: new Uint8Array(wasmBinary),
});

expect(result.resultAsString).toEqual('ok');
expect(result.exitCode).toBe(0);
});

it('should error on invalid u8 json arrays', async () => {
const wasmBinary = await readFile(
'dist/libs/as-sdk-integration-tests/debug.wasm'
);
const result = await callVm({
args: ['testInvalidUint8JsonArray'],
envs: {},
binary: new Uint8Array(wasmBinary),
});

expect(result.stderr).toContain('abort: Invalid u8 299');
expect(result.exitCode).toBe(255);
});
});
3 changes: 3 additions & 0 deletions libs/as-sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# AssemblyScript SDK

SDK for creating Data Requests on the SEDA chain
24 changes: 24 additions & 0 deletions libs/as-sdk/as-pect.asconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"targets": {
"coverage": {
"lib": ["../../node_modules/@as-covers/assembly/index.ts"],
"transform": ["@as-covers/transform", "@as-pect/transform"]
},
"noCoverage": {
"transform": ["@as-pect/transform"]
}
},
"options": {
"exportMemory": true,
"outFile": "output.wasm",
"textFile": "output.wat",
"bindings": "raw",
"exportStart": "_start",
"exportRuntime": true,
"use": ["RTRACE=1"],
"debug": true,
"exportTable": true
},
"extends": "./asconfig.json",
"entries": ["../../node_modules/@as-pect/assembly/assembly/index.ts"]
}
32 changes: 32 additions & 0 deletions libs/as-sdk/as-pect.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default {
/**
* A set of globs passed to the glob package that qualify typescript files for testing.
*/
entries: ['./assembly/__test__/**/*.spec.ts'],
/**
* A set of globs passed to the glob package that quality files to be added to each test.
*/
include: ['./assembly/__test__/**/*.include.ts'],
/**
* A set of regexp that will disclude source files from testing.
*/
disclude: [/node_modules/],
/**
* Add your required AssemblyScript imports here.
*/
async instantiate(memory, createImports, instantiate, binary) {
let instance; // Imports can reference this
const myImports = {
env: { memory },
// put your web assembly imports here, and return the module promise
};
instance = instantiate(binary, createImports(myImports));
return instance;
},
/** Enable code coverage. */
// coverage: ["assembly/**/*.ts"],
/**
* Specify if the binary wasm file should be written to the file system.
*/
outputBinary: false,
};
23 changes: 23 additions & 0 deletions libs/as-sdk/asconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"extends": "../../node_modules/@assemblyscript/wasi-shim/asconfig.json",
"targets": {
"debug": {
"outFile": "../../dist/libs/as-sdk/debug.wasm",
"textFile": "../../dist/libs/as-sdk/debug.wat",
"sourceMap": true,
"debug": true
},
"release": {
"outFile": "../../dist/libs/as-sdk/release.wasm",
"textFile": "../../dist/libs/as-sdk/release.wat",
"sourceMap": true,
"optimizeLevel": 3,
"shrinkLevel": 0,
"converge": false,
"noAssert": false
}
},
"options": {
"bindings": "esm"
}
}
11 changes: 11 additions & 0 deletions libs/as-sdk/assembly/bindings/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export declare function http_fetch(
action_ptr: usize,
action_length: u32
): u32;

export declare function call_result_write(
result: usize,
result_length: u32
): void;

export declare function execution_result(result: usize, result_length: u32): void;
Loading