Skip to content

Commit

Permalink
refactor many more examples
Browse files Browse the repository at this point in the history
  • Loading branch information
lastmjs committed Jan 28, 2025
1 parent 0ac08c1 commit 1672ac4
Show file tree
Hide file tree
Showing 14 changed files with 384 additions and 243 deletions.
2 changes: 2 additions & 0 deletions agent_execution_protocol_one_file.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ TODOs
15. It isn't recognizing that something has already been checked off, it's trying to execute tasks that have checks
16. Use placeholders instead of actual paths
17. Sometimes it won't even write files into the project_plan.md file
18. Every time you ask the agent to go to step 9, explain that it should go to step 9 of the execution protocol, and then go to step 10, 11, 12, and 13 and execute them exactly
19. We should try to instruct it to ask for help if it needs help...so that it doesn't hallucinate
22 changes: 22 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Azle Examples and Tests

## TLDR

Use the `examples` directory to learn how to use Azle.

Stable mode examples are in the `stable` directory.

Experimental mode examples are in the `experimental` directory.

## Examples

The `examples` directory is used for both automated testing and end-developer education. Please freely peruse the examples to learn how to use Azle; It's probably the best documentation that you'll find.

We use various directory names to indicate higher-level purposes:

- `demo`: Intended as more complete and easy-to-understand examples
- `test`: Intended as possibly more confusing and less finished examples that are used for automated testing
- `end_to_end`: Simple example-based tests that call into a canister using the JavaScript agent or `dfx`
- `property`: Property-based tests that attempt to test canisters under arbitrary inputs
- `candid_rpc`: Tests for the Candid RPC (remote procedure call) ICP APIs (`@query`, `@update`, Candid, `IDL`, etc)
- `http_server`: Tests for the HTTP Server functionality, doing away with Candid RPC and focusing on core web 2 APIs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { call, IDL, trap } from 'azle';
import {
Canister,
ic,
Principal,
query,
Record,
Expand Down Expand Up @@ -37,33 +37,31 @@ export default Canister({
return someCanisters;
}
),
canisterCrossCanisterCall: update(
[SomeCanister],
text,
async (someCanister) => {
if (process.env.AZLE_TEST_FETCH === 'true') {
const response = await fetch(
`icp://${getSomeCanisterPrincipal()}/update1`,
{
body: serialize({
candidPath: `/candid/some_canister.did`
})
}
);
const responseJson = await response.json();
canisterCrossCanisterCall: update([SomeCanister], text, async () => {
if (process.env.AZLE_TEST_FETCH === 'true') {
const response = await fetch(
`icp://${getSomeCanisterPrincipal()}/update1`,
{
body: serialize({
candidPath: `/candid/some_canister.did`
})
}
);
const responseJson = await response.json();

return responseJson;
} else {
return await ic.call(someCanister.update1);
}
return responseJson;
} else {
return await call(getSomeCanisterPrincipal(), 'update1', {
returnIdlType: IDL.Text
});
}
)
})
});

function getSomeCanisterPrincipal(): string {
if (process.env.SOME_CANISTER_PRINCIPAL !== undefined) {
return process.env.SOME_CANISTER_PRINCIPAL;
}

throw new Error(`process.env.SOME_CANISTER_PRINCIPAL is not defined`);
trap(`process.env.SOME_CANISTER_PRINCIPAL is not defined`);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { call, IDL, notify } from 'azle';
import {
Canister,
ic,
init,
nat64,
None,
Opt,
Principal,
serialize,
Some,
text,
Expand All @@ -14,15 +12,9 @@ import {
Void
} from 'azle/experimental';

import Canister2 from '../canister2';
import { Account, AccountArgs } from '../canister2/types';

let canister2: typeof Canister2;

export default Canister({
init: init([], () => {
canister2 = Canister2(Principal.fromText(getCanister2Principal()));
}),
transfer: update([text, text, nat64], nat64, async (from, to, amount) => {
if (process.env.AZLE_TEST_FETCH === 'true') {
const response = await fetch(
Expand All @@ -38,7 +30,9 @@ export default Canister({

return responseJson;
} else {
return await ic.call(canister2.transfer, {
return await call(getCanister2Principal(), 'transfer', {
paramIdlTypes: [IDL.Text, IDL.Text, IDL.Nat64],
returnIdlType: IDL.Nat64,
args: [from, to, amount]
});
}
Expand All @@ -58,7 +52,9 @@ export default Canister({

return responseJson;
} else {
return await ic.call(canister2.balance, {
return await call(getCanister2Principal(), 'balance', {
paramIdlTypes: [IDL.Text],
returnIdlType: IDL.Nat64,
args: [id]
});
}
Expand All @@ -82,7 +78,17 @@ export default Canister({
return None;
}
} else {
return await ic.call(canister2.account, {
const AccountIdl = IDL.Record({
id: IDL.Text,
balance: IDL.Nat64
});
const AccountArgsIdl = IDL.Record({
id: IDL.Text
});

return await call(getCanister2Principal(), 'account', {
paramIdlTypes: [AccountArgsIdl],
returnIdlType: IDL.Opt(AccountIdl),
args: [args]
});
}
Expand All @@ -102,7 +108,14 @@ export default Canister({

return responseJson;
} else {
return await ic.call(canister2.accounts, {
const AccountIdl = IDL.Record({
id: IDL.Text,
balance: IDL.Nat64
});

return await call(getCanister2Principal(), 'accounts', {
paramIdlTypes: [],
returnIdlType: IDL.Vec(AccountIdl),
args: []
});
}
Expand All @@ -122,15 +135,17 @@ export default Canister({

return responseJson;
} else {
return await ic.call(canister2.trap, {
return await call(getCanister2Principal(), 'trap', {
paramIdlTypes: [],
returnIdlType: IDL.Text,
args: []
});
}
}),
sendNotification: update([], Void, () => {
// TODO for now there seems to be no fetch analogy because notify must be synchronous
// TODO and fetch must be asynchronous
return ic.notify(canister2.receiveNotification, {
return notify(getCanister2Principal(), 'receiveNotification', {
args: ['This is the notification'],
cycles: 10n
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { trap } from 'azle';
import {
Canister,
ic,
nat64,
None,
Opt,
Expand Down Expand Up @@ -59,7 +59,7 @@ export default Canister({
return Object.values(state.accounts);
}),
trap: query([], text, () => {
ic.trap('hahahaha');
trap('hahahaha');
return 'You will never get here';
}),
receiveNotification: update([text], Void, (message) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Canister, ic, nat, query, update } from 'azle/experimental';
import { canisterBalance, msgCyclesAccept, msgCyclesAvailable } from 'azle';
import { Canister, nat, query, update } from 'azle/experimental';

export default Canister({
receiveCycles: update([], nat, () => {
return ic.msgCyclesAccept(ic.msgCyclesAvailable() / 2n);
return msgCyclesAccept(msgCyclesAvailable() / 2n);
}),
getCanisterBalance: query([], nat, () => {
return ic.canisterBalance();
return canisterBalance();
})
});
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
import { call, canisterBalance, notify, trap } from 'azle';
import {
Canister,
ic,
init,
nat,
Principal,
query,
serialize,
update,
Void
} from 'azle/experimental';

import Cycles from '../cycles';

let cyclesCanister: typeof Cycles;

export default Canister({
init: init([], () => {
cyclesCanister = Cycles(Principal.fromText(getCyclesPrincipal()));
}),
// Reports the number of cycles returned from the Cycles canister
sendCycles: update([], nat, async () => {
if (process.env.AZLE_TEST_FETCH === 'true') {
Expand All @@ -34,24 +25,24 @@ export default Canister({

return responseJson;
} else {
return await ic.call(cyclesCanister.receiveCycles, {
return await call(getCyclesPrincipal(), 'receiveCycles', {
cycles: 1_000_000n
});
}
}),
sendCyclesNotify: update([], Void, () => {
return ic.notify(cyclesCanister.receiveCycles, {
return notify(getCyclesPrincipal(), 'receiveCycles', {
cycles: 1_000_000n
});
}),
getCanisterBalance: query([], nat, () => {
return ic.canisterBalance();
return canisterBalance();
})
});

function getCyclesPrincipal(): string {
return (
process.env.CYCLES_PRINCIPAL ??
ic.trap('process.env.CYCLES_PRINCIPAL is undefined')
trap('process.env.CYCLES_PRINCIPAL is undefined')
);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { call, IDL } from 'azle';
import {
Canister,
Func,
ic,
init,
nat64,
Null,
Expand All @@ -19,7 +19,7 @@ import {
Void
} from 'azle/experimental';

import Notifier, { NotifierFunc } from '../notifiers';
import { NotifierFunc } from '../notifiers';

const BasicFunc = Func([text], text, 'query');
type BasicFunc = typeof BasicFunc.tsType;
Expand Down Expand Up @@ -104,13 +104,11 @@ export default Canister({
}),

getNotifierFromNotifiersCanister: update([], NotifierFunc, async () => {
const notifiersCanister = Notifier(
Principal.fromText(getNotifierPrincipal())
);
const notifierPrincipal = getNotifierPrincipal();

if (process.env.AZLE_TEST_FETCH === 'true') {
const response = await fetch(
`icp://${getNotifierPrincipal()}/getNotifier`,
`icp://${notifierPrincipal}/getNotifier`,
{
body: serialize({
candidPath: `/candid/notifiers.did`
Expand All @@ -121,7 +119,9 @@ export default Canister({

return responseJson;
} else {
return await ic.call(notifiersCanister.getNotifier);
return await call(notifierPrincipal, 'getNotifier', {
returnIdlType: IDL.Func([IDL.Vec(IDL.Nat8)], [], ['oneway'])
});
}
})
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { trap } from 'azle';
import {
blob,
Canister,
Func,
ic,
Principal,
query,
Void
Expand All @@ -16,7 +16,7 @@ export default Canister({
return [
Principal.fromText(
process.env.NOTIFIERS_PRINCIPAL ??
ic.trap('process.env.NOTIFIERS_PRINCIPAL is undefined')
trap('process.env.NOTIFIERS_PRINCIPAL is undefined')
),
'notify'
];
Expand Down
Loading

0 comments on commit 1672ac4

Please sign in to comment.