Skip to content

Commit

Permalink
Showing 22 changed files with 10,917 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -73,6 +73,7 @@ jobs:
"examples/bitcoin_psbt",
"examples/ckbtc",
"examples/hello_world",
"examples/hello_world_candid_rpc",
"property_tests/tests/blob",
"property_tests/tests/bool",
"property_tests/tests/canister_methods/http_request",
@@ -150,6 +151,7 @@ jobs:
"tests/end_to_end/candid_rpc/class_syntax/motoko_examples/threshold_ecdsa",
"tests/end_to_end/candid_rpc/class_syntax/motoko_examples/whoami",
"tests/end_to_end/candid_rpc/class_syntax/new",
"tests/end_to_end/candid_rpc/class_syntax/new_candid_rpc",
"tests/end_to_end/candid_rpc/class_syntax/notify_raw",
"tests/end_to_end/candid_rpc/class_syntax/null_example",
"tests/end_to_end/candid_rpc/class_syntax/optional_types",
4 changes: 4 additions & 0 deletions examples/hello_world_candid_rpc/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.azle
.dfx
dfx_generated
node_modules
84 changes: 84 additions & 0 deletions examples/hello_world_candid_rpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Azle Hello World

- [Installation](#installation)
- [Deployment](#deployment)

Azle helps you to build secure decentralized/replicated servers in TypeScript or JavaScript on [ICP](https://internetcomputer.org/). The current replication factor is [13-40 times](https://dashboard.internetcomputer.org/subnets).

Please remember that Azle is in beta and thus it may have unknown security vulnerabilities due to the following:

- Azle is built with various software packages that have not yet reached maturity
- Azle does not yet have multiple independent security reviews/audits
- Azle does not yet have many live, successful, continuously operating applications deployed to ICP

## Installation

> Windows is only supported through a Linux virtual environment of some kind, such as [WSL](https://learn.microsoft.com/en-us/windows/wsl/install)
You will need [Node.js 20](#nodejs-20) and [dfx](#dfx) to develop ICP applications with Azle:

### Node.js 20

It's recommended to use nvm to install Node.js 20:

```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
```

Restart your terminal and then run:

```bash
nvm install 20
```

Check that the installation went smoothly by looking for clean output from the following command:

```bash
node --version
```

### dfx

Install the dfx command line tools for managing ICP applications:

```bash
DFX_VERSION=0.21.0 sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)"
```

Check that the installation went smoothly by looking for clean output from the following command:

```bash
dfx --version
```

## Deployment

To create and deploy a simple sample application called `hello_world`:

```bash
# create a new default project called hello_world
npx azle new hello_world
cd hello_world
```

```bash
# install all npm dependencies including azle
npm install
```

```bash
# install the azle dfx extension
npx azle install-dfx-extension
```

```bash
# start up a local ICP replica
dfx start --clean
```

In a separate terminal in the `hello_world` directory:

```bash
# deploy your canister
dfx deploy
```
13 changes: 13 additions & 0 deletions examples/hello_world_candid_rpc/dfx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"canisters": {
"hello_world": {
"type": "azle",
"main": "src/index.ts",
"candid_gen": "automatic",
"declarations": {
"output": "test/dfx_generated/hello_world",
"node_compatibility": true
}
}
}
}
10 changes: 10 additions & 0 deletions examples/hello_world_candid_rpc/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
transform: {
'^.+\\.ts$': 'ts-jest',
'^.+\\.js$': 'ts-jest'
},
transformIgnorePatterns: ['/node_modules/(?!(azle)/)'] // Make sure azle is transformed
};
5,863 changes: 5,863 additions & 0 deletions examples/hello_world_candid_rpc/package-lock.json

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions examples/hello_world_candid_rpc/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"scripts": {
"pretest": "tsx test/pretest.ts",
"test": "jest"
},
"dependencies": {
"azle": "0.22.0"
},
"devDependencies": {
"jest": "^29.7.0",
"ts-jest": "^29.1.4",
"tsx": "^4.15.7",
"typescript": "^5.2.2"
}
}
15 changes: 15 additions & 0 deletions examples/hello_world_candid_rpc/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { IDL, query, update } from 'azle';

export default class {
message: string = 'Hello world!';

@query([], IDL.Text)
getMessage(): string {
return this.message;
}

@update([IDL.Text])
setMessage(message: string): void {
this.message = message;
}
}
17 changes: 17 additions & 0 deletions examples/hello_world_candid_rpc/test/pretest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { execSync } from 'child_process';

function pretest(): void {
execSync(`dfx canister uninstall-code hello_world || true`, {
stdio: 'inherit'
});

execSync(`dfx deploy hello_world`, {
stdio: 'inherit'
});

execSync(`dfx generate hello_world`, {
stdio: 'inherit'
});
}

pretest();
13 changes: 13 additions & 0 deletions examples/hello_world_candid_rpc/test/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { getCanisterId } from 'azle/dfx';
import { runTests } from 'azle/test';

import { createActor } from './dfx_generated/hello_world';
import { getTests } from './tests';

const helloWorldCanister = createActor(getCanisterId('hello_world'), {
agentOptions: {
host: 'http://127.0.0.1:8000'
}
});

runTests(getTests(helloWorldCanister));
28 changes: 28 additions & 0 deletions examples/hello_world_candid_rpc/test/tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ActorSubclass } from '@dfinity/agent';
import { expect, it, Test } from 'azle/test';

// @ts-ignore this path may not exist when these tests are imported into other test projects
import { _SERVICE } from './dfx_generated/hello_world/hello_world.did';

export function getTests(helloWorldCanister: ActorSubclass<_SERVICE>): Test {
return () => {
it('gets original message', async () => {
const result = await helloWorldCanister.getMessage();

expect(result).toBe('Hello world!');
});

it('sets a new message', async () => {
const result =
await helloWorldCanister.setMessage('Goodbye world!');

expect(result).toBeUndefined();
});

it('gets persisted new message', async () => {
const result = await helloWorldCanister.getMessage();

expect(result).toBe('Goodbye world!');
});
};
}
9 changes: 9 additions & 0 deletions examples/hello_world_candid_rpc/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"compilerOptions": {
"strict": true,
"target": "ES2020",
"moduleResolution": "node",
"allowJs": true,
"outDir": "HACK_BECAUSE_OF_ALLOW_JS"
}
}
14 changes: 8 additions & 6 deletions src/compiler/new_command.ts
Original file line number Diff line number Diff line change
@@ -14,14 +14,16 @@ export async function generateNewAzleProject(
}

const projectName = process.argv[3];
const flag = process.argv[4];

await copy(join(AZLE_PACKAGE_PATH, 'examples', 'hello_world'), projectName);
const path =
flag === '--http-server'
? join(AZLE_PACKAGE_PATH, 'examples', 'hello_world')
: join(AZLE_PACKAGE_PATH, 'examples', 'hello_world_candid_rpc');

const packageJson = (
await readFile(
join(AZLE_PACKAGE_PATH, 'examples', 'hello_world', 'package.json')
)
).toString();
await copy(path, projectName);

const packageJson = (await readFile(join(path, 'package.json'))).toString();

let parsedPackageJson = JSON.parse(packageJson);

Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ import { execSync } from 'child_process';
import { version } from '../../../../../../package.json';

function pretest(): void {
execSync(`npx -y azle@${version} new hello_world`, {
execSync(`npx -y azle@${version} new hello_world --http-server`, {
stdio: 'inherit'
});

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.azle
.dfx
dfx_generated
hello_world
node_modules
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
transform: {
'^.+\\.ts$': 'ts-jest',
'^.+\\.js$': 'ts-jest'
},
transformIgnorePatterns: ['/node_modules/(?!(azle)/)'] // Make sure azle is transformed
};
4,723 changes: 4,723 additions & 0 deletions tests/end_to_end/candid_rpc/class_syntax/new_candid_rpc/package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "new_end_to_end_test_functional_syntax",
"scripts": {
"pretest": "if [ \"$AZLE_QUICK_TEST\" != \"true\" ]; then tsx test/pretest.ts; else echo 'Skipping pretests'; fi",
"test": "if [ \"$AZLE_QUICK_TEST\" != \"true\" ]; then jest; else echo 'Skipping tests'; fi"
},
"devDependencies": {
"@dfinity/agent": "^0.19.2",
"jest": "^29.7.0",
"ts-jest": "^29.1.5",
"tsx": "^4.15.7",
"typescript": "^5.2.2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { execSync } from 'child_process';

import { version } from '../../../../../../package.json';

function pretest(): void {
execSync(`npx -y azle@${version} new hello_world`, {
stdio: 'inherit'
});

execSync(`npx -y azle@${version} install-dfx-extension`, {
stdio: 'inherit'
});

execSync(`cd hello_world && dfx canister uninstall-code backend || true`, {
stdio: 'inherit'
});

execSync(`cd hello_world && npm install`, {
stdio: 'inherit'
});

execSync(`cd hello_world && dfx deploy`, {
stdio: 'inherit'
});

execSync(`cd hello_world && dfx generate`, {
stdio: 'inherit'
});
}

pretest();
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// TODO if these tests break just delete azle/examples/hello_world/node_modules

import { getCanisterId } from '../../../../../../dfx'; // We don't want to install Azle
import { runTests } from '../../../../../../test'; // We don't want to install Azle
import { createActor } from './dfx_generated/hello_world';
import { getTests } from './tests';

const helloWorldCanister = createActor(getCanisterId('hello_world'), {
agentOptions: {
host: 'http://127.0.0.1:8000'
}
});

runTests(getTests(helloWorldCanister));
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ActorSubclass } from '@dfinity/agent';
import { expect, it, Test } from 'azle/test';

// @ts-ignore this path may not exist when these tests are imported into other test projects
import { _SERVICE } from './dfx_generated/hello_world/hello_world.did';

export function getTests(helloWorldCanister: ActorSubclass<_SERVICE>): Test {
return () => {
it('gets original message', async () => {
const result = await helloWorldCanister.getMessage();

expect(result).toBe('Hello world!');
});

it('sets a new message', async () => {
const result =
await helloWorldCanister.setMessage('Goodbye world!');

expect(result).toBeUndefined();
});

it('gets persisted new message', async () => {
const result = await helloWorldCanister.getMessage();

expect(result).toBe('Goodbye world!');
});
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"strict": true,
"target": "ES2020",
"moduleResolution": "node",
"allowJs": true,
"outDir": "HACK_BECAUSE_OF_ALLOW_JS",
"resolveJsonModule": true
}
}

0 comments on commit 2bfa902

Please sign in to comment.