You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* docs: example calls typescript
Signed-off-by: David Dal Busco <david.dalbusco@outlook.com>
* 📄 Update LLMs.txt snapshot for PR review
---------
Signed-off-by: David Dal Busco <david.dalbusco@outlook.com>
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Copy file name to clipboardExpand all lines: .llms-snapshots/llms-full.txt
+184-2Lines changed: 184 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -2233,7 +2233,7 @@ Write serverless backend logic for your app using TypeScript or Rust. These exam
2233
2233
2234
2234
[## 🗃️ TypeScript
2235
2235
2236
-
2 items](/docs/examples/functions/typescript.md)
2236
+
3 items](/docs/examples/functions/typescript.md)
2237
2237
2238
2238
# Angular Example
2239
2239
@@ -3189,6 +3189,10 @@ An example demonstrating how to write custom assertions in TypeScript for Juno s
3189
3189
3190
3190
An example demonstrating how to modify and re-save documents in Juno Satellites using TypeScript hooks.](/docs/examples/functions/typescript/mutating-docs.md)
3191
3191
3192
+
[## 📄️ Canister Calls
3193
+
3194
+
An example showing how to call external canisters (e.g., ICRC ledger) from a serverless function written in TypeScript using Juno Satellites.](/docs/examples/functions/typescript/canister-calls.md)
3195
+
3192
3196
# Rust Assertion Example
3193
3197
3194
3198
This example demonstrates how to write a **custom assertion** in **Rust** for a Juno **serverless function**. It shows how to intercept and validate data operations—such as rejecting specific content—before it's written to the datastore.
@@ -3549,7 +3553,9 @@ These crates are used to build and extend serverless functions in Rust with Juno
3549
3553
* [junobuild-shared](https://docs.rs/junobuild-shared): Shared types and helpers for Juno projects. Used by all containers including the Console.
3550
3554
* [junobuild-storage](https://docs.rs/junobuild-storage): Storage helpers for working with assets and HTTP headers in Juno.
3551
3555
3552
-
\* [icrc-ledger-types](https://docs.rs/icrc-ledger-types): Types for interacting with the ICRC ledger standard. \* [ic-cdk](https://docs.rs/ic-cdk): Internet Computer canister development kit for Rust.
3556
+
* [icrc-ledger-types](https://docs.rs/icrc-ledger-types): Types for interacting with the ICRC ledger standard.
3557
+
3558
+
* [ic-cdk](https://docs.rs/ic-cdk): Internet Computer canister development kit for Rust.
3553
3559
3554
3560
# Generating Assets with Rust Serverless Functions
3555
3561
@@ -4051,6 +4057,182 @@ It’s a great reference for more advanced setups and orchestration.
# Making Canister Calls in TypeScript Serverless Functions
4061
+
4062
+
This example demonstrates how to use **TypeScript serverless functions** to perform canister calls (such as `transfer_from` on the ICP ledger) in response to Datastore events in your Juno **Satellite**.
4063
+
4064
+
When a document is added to the `request` collection, a serverless function is triggered to:
4065
+
4066
+
* Check if the user has enough ICP in their wallet
4067
+
* Transfer ICP from the user's wallet to the Satellite using the ICRC ledger's `transfer_from` method
4068
+
* Mark the request as `processed` if the transfer succeeds
4069
+
4070
+
This pattern is useful for building workflows that require on-chain asset transfers or other canister calls in response to user actions.
4071
+
4072
+
You can browse the source code here: [github.com/junobuild/examples/tree/main/functions/typescript/calls](https://github.com/junobuild/examples/tree/main/functions/typescript/calls)
* **Serverless Canister Calls**: Demonstrates how to perform ICRC ledger calls (e.g., `transfer_from`) from TypeScript serverless functions.
4087
+
* **Atomic Request Processing**: Ensures that request status is only updated if the transfer succeeds.
4088
+
* **Wallet Balance Checks**: Fails early if the user does not have enough ICP.
4089
+
* **Minimal React UI**: A simple React frontend is included to test and demonstrate the logic.
4090
+
4091
+
---
4092
+
4093
+
## Main Backend Components
4094
+
4095
+
* **src/satellite/index.ts**: The entry point for the Satellite serverless function. Triggers the canister call and updates request status on document set.
4096
+
* **src/satellite/services.ts**: Helper logic for checking wallet balance, performing the transfer, and updating request status.
4097
+
* **src/satellite/ledger-icrc.ts**: Helper functions for interacting with the ICRC ledger.
4098
+
* **src/types/request.ts**: Data model for requests and status.
4099
+
4100
+
---
4101
+
4102
+
## Example: Canister Call on Document Set
4103
+
4104
+
Here’s the actual TypeScript logic from `index.ts` and `services.ts`:
4105
+
4106
+
```
4107
+
// src/satellite/index.tsimport { Account } from "@dfinity/ledger-icrc/dist/candid/icrc_ledger";import { Principal } from "@dfinity/principal";import { type AssertSetDoc, defineAssert, defineHook, type OnSetDoc} from "@junobuild/functions";import { id } from "@junobuild/functions/ic-cdk";import { decodeDocData } from "@junobuild/functions/sdk";import { COLLECTION_REQUEST, ICP_LEDGER_ID } from "../constants/app.constants";import { RequestData, RequestDataSchema } from "../types/request";import { assertWalletBalance, setRequestProcessed, transferIcpFromWallet} from "./services";export const assertSetDoc = defineAssert<AssertSetDoc>({ collections: [COLLECTION_REQUEST], assert: (context) => { // We validate that the data submitted for create or update matches the expected schema. const person = decodeDocData<RequestData>(context.data.data.proposed.data); RequestDataSchema.parse(person); }});export const onSetDoc = defineHook<OnSetDoc>({ collections: [COLLECTION_REQUEST], run: async (context) => { // Init data const { data: { key, data: { after: { version } } } } = context; const data = decodeDocData<RequestData>(context.data.data.after.data); const { amount: requestAmount, fee } = data; const ledgerId = ICP_LEDGER_ID; const fromAccount: Account = { owner: Principal.fromUint8Array(context.caller), subaccount: [] }; // Check current account balance await assertWalletBalance({ ledgerId, fromAccount, amount: requestAmount, fee }); // Update request status to processed (atomic with transfer) setRequestProcessed({ key, version, data }); // Transfer from wallet to satellite const toAccount: Account = { owner: id(), subaccount: [] }; await transferIcpFromWallet({ ledgerId, fromAccount, toAccount, amount: requestAmount, fee }); }});
Requires the Juno CLI to be available `npm i -g @junobuild/cli`
4142
+
4143
+
```
4144
+
juno dev start
4145
+
```
4146
+
4147
+
4. **Create a Satellite** for local dev:
4148
+
4149
+
* Visit [http://localhost:5866](http://localhost:5866) and follow the instructions.
4150
+
* Update `juno.config.ts` with your Satellite ID.
4151
+
4152
+
5. **Create required collections**:
4153
+
4154
+
* `request` in Datastore: [http://localhost:5866/datastore](http://localhost:5866/datastore)
4155
+
4156
+
6. **Start the frontend dev server** (in a separate terminal):
4157
+
4158
+
```
4159
+
npm run dev
4160
+
```
4161
+
4162
+
7. **Build the serverless functions** (in a separate terminal):
4163
+
4164
+
```
4165
+
juno functions build
4166
+
```
4167
+
4168
+
The emulator will automatically upgrade your Satellite and live reload the changes.
4169
+
4170
+
---
4171
+
4172
+
## Juno-Specific Configuration
4173
+
4174
+
* **juno.config.ts**: Defines Satellite IDs for development/production, build source, and predeploy steps. See the [Configuration reference](/docs/reference/configuration.md) for details.
4175
+
* **vite.config.ts**: Registers the `juno` plugin to inject environment variables automatically. See the [Vite Plugin reference](/docs/reference/plugins.md#vite-plugin) for more information.
4176
+
4177
+
---
4178
+
4179
+
## Production Deployment
4180
+
4181
+
* Create a Satellite on the [Juno Console](https://console.juno.build) for mainnet.
4182
+
* Update `juno.config.ts` with the production Satellite ID.
4183
+
* Build and deploy the frontend:
4184
+
4185
+
```
4186
+
npm run buildjuno deploy
4187
+
```
4188
+
4189
+
* Build and upgrade the serverless functions:
4190
+
4191
+
```
4192
+
juno functions buildjuno functions upgrade
4193
+
```
4194
+
4195
+
---
4196
+
4197
+
## Notes
4198
+
4199
+
* This example focuses on the TypeScript serverless function. The frontend is intentionally minimal and included only for demonstration.
4200
+
* Use this project as a starting point for writing custom backend logic in TypeScript using Juno serverless functions and canister calls.
4201
+
4202
+
---
4203
+
4204
+
## Real-World Example
4205
+
4206
+
Want to see how assertions and serverless logic are used in a live project?
4207
+
4208
+
Check out [cycles.watch](https://cycles.watch), an open-source app built with Juno:
This example demonstrates how to use **hooks in TypeScript** to modify documents automatically when they're created or updated in your Juno **Satellite**.
Copy file name to clipboardExpand all lines: .llms-snapshots/llms.txt
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -76,6 +76,7 @@ Juno is your self-contained serverless platform for building full-stack web apps
76
76
## Examples - Functions - Typescript
77
77
78
78
- [TypeScript Assertions Example](https://juno.build/docs/examples/functions/typescript/assertion.md): An example demonstrating how to write custom assertions in TypeScript for Juno serverless functions.
79
+
- [Making Canister Calls in TypeScript Serverless Functions](https://juno.build/docs/examples/functions/typescript/canister-calls.md): An example showing how to call external canisters (e.g., ICRC ledger) from a serverless function written in TypeScript using Juno Satellites.
79
80
- [Mutating Documents with TypeScript Hooks](https://juno.build/docs/examples/functions/typescript/mutating-docs.md): An example demonstrating how to modify and re-save documents in Juno Satellites using TypeScript hooks.
0 commit comments