Skip to content

Commit

Permalink
Create node example
Browse files Browse the repository at this point in the history
  • Loading branch information
tarrencev committed Jan 28, 2025
1 parent 67b4327 commit 96a4748
Show file tree
Hide file tree
Showing 18 changed files with 1,431 additions and 131 deletions.
1 change: 1 addition & 0 deletions examples/node/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.cartridge
40 changes: 40 additions & 0 deletions examples/node/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Cartridge Node.js Session Example

This example demonstrates how to use the Cartridge session controller with Node.js, utilizing a filesystem backend for storage.

## Setup

1. Install dependencies:
```bash
npm install
```

2. Configure environment (optional):
```bash
export CARTRIDGE_STORAGE_PATH="./my-storage-path" # Default is "./cartridge-storage"
```

3. Run the example:
```bash
npm start
```

## What's happening?

The example demonstrates:
1. Setting up a filesystem backend for session storage
2. Creating a session controller instance
3. Creating a new session with specific policies
4. Executing a transaction using the session

## Customization

To use this example with your own contract:

1. Replace the contract address (`0x123...`) with your actual contract address
2. Modify the policies to match your contract's methods
3. Update the transaction parameters in the `execute` call to match your use case

## Storage

By default, session data is stored in the `./cartridge-storage` directory. You can change this by setting the `CARTRIDGE_STORAGE_PATH` environment variable.
21 changes: 21 additions & 0 deletions examples/node/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "cartridge-node-example",
"version": "1.0.0",
"description": "Example of using Cartridge session controller with Node.js",
"type": "module",
"scripts": {
"build": "tsc",
"start": "node --experimental-wasm-modules dist/session.js",
"dev": "node --experimental-wasm-modules --import tsx src/session.ts"
},
"dependencies": {
"@cartridge/account-wasm": "workspace:*",
"@cartridge/controller": "workspace:*",
"starknet": "catalog:"
},
"devDependencies": {
"typescript": "^5.3.3",
"tsx": "^4.7.0",
"@types/node": "^22.12.0"
}
}
74 changes: 74 additions & 0 deletions examples/node/src/session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import SessionProvider, {
ControllerError,
} from "@cartridge/controller/session/node";
import { constants, ec, stark } from "starknet";
import path from "path";

export const STRK_CONTRACT_ADDRESS =
"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7";

async function main() {
// Path to store session
const storagePath =
process.env.CARTRIDGE_STORAGE_PATH ||
path.join(process.cwd(), ".cartridge");

// Create a session provider
const provider = new SessionProvider({
rpc: "https://api.cartridge.gg/x/starknet/sepolia",
chainId: constants.StarknetChainId.SN_SEPOLIA,
policies: {
contracts: {
[STRK_CONTRACT_ADDRESS]: {
methods: [
{
name: "approve",
entrypoint: "approve",
description: "Approve spending of tokens",
},
{ name: "transfer", entrypoint: "transfer" },
],
},
},
},
basePath: storagePath,
});
try {
// Connect and create session
const account = await provider.connect();
console.log("Session initialized!");

if (account) {
console.log("Account address:", account.address);

// Example: Transfer ETH
const amount = "0x0";
const recipient = account.address; // Replace with actual recipient address

const result = await account.execute([
{
contractAddress: STRK_CONTRACT_ADDRESS,
entrypoint: "transfer",
calldata: [recipient, amount, "0x0"],
},
]);

console.log("Transaction hash:", result.transaction_hash);
} else {
console.log("Please complete the session creation in your browser");
}
} catch (error: unknown) {
const controllerError = error as ControllerError;
if (controllerError.code) {
console.error("Session error:", {
code: controllerError.code,
message: controllerError.message,
data: controllerError.data,
});
} else {
console.error("Session error:", error);
}
}
}

main().catch(console.error);
16 changes: 16 additions & 0 deletions examples/node/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"allowJs": true,
"resolveJsonModule": true
},
"include": ["src/**/*"]
}
8 changes: 0 additions & 8 deletions packages/account-wasm/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,3 @@ pnpm wasm-pack build --target bundler --out-dir ./pkg-controller --release --fea

# Build session bundle
pnpm wasm-pack build --target bundler --out-dir ./pkg-session --release --features "console-error-panic,session_account"

# Workaround for ESM `import` error in NextJS.
# This removes `"type": "module"` field from the package.json files
for dir in pkg-controller pkg-session; do
mv $dir/package.json $dir/temp.json
jq -r 'del(.type)' $dir/temp.json >$dir/package.json
rm $dir/temp.json
done
43 changes: 14 additions & 29 deletions packages/account-wasm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,40 @@
"name": "@cartridge/account-wasm",
"version": "0.6.0",
"description": "Wasm bindings for Cartridge Controller and Session Account",
"main": "./pkg-controller/account_wasm.js",
"type": "module",
"main": "./pkg-controller/account_wasm.js",
"module": "./pkg-controller/account_wasm.js",
"types": "./pkg-controller/account_wasm.d.ts",
"scripts": {
"build:deps": "./build.sh"
},
"files": [
"./pkg-controller/account_wasm_bg.wasm",
"./pkg-controller/account_wasm.js",
"./pkg-controller/account_wasm_bg.js",
"./pkg-controller/account_wasm.d.ts",
"./pkg-session/account_wasm_bg.wasm",
"./pkg-session/account_wasm.js",
"./pkg-session/account_wasm_bg.js",
"./pkg-session/account_wasm.d.ts"
"pkg-controller",
"pkg-session"
],
"exports": {
".": {
"types": "./pkg-controller/account_wasm.d.ts",
"default": "./pkg-controller/account_wasm.js"
"import": "./pkg-controller/account_wasm.js",
"require": "./pkg-controller/account_wasm.js"
},
"./controller": {
"types": "./pkg-controller/account_wasm.d.ts",
"default": "./pkg-controller/account_wasm.js"
"import": "./pkg-controller/account_wasm.js",
"require": "./pkg-controller/account_wasm.js"
},
"./session": {
"types": "./pkg-session/account_wasm.d.ts",
"default": "./pkg-session/account_wasm.js"
"import": "./pkg-session/account_wasm.js",
"require": "./pkg-session/account_wasm.js"
}
},
"sideEffects": [
"**/*.wasm",
"./pkg-controller/account_wasm.js",
"./pkg-session/account_wasm.js",
"./pkg-controller/snippets/*",
"./pkg-session/snippets/*"
"./pkg-session/account_wasm.js"
],
"typesVersions": {
"*": {
"controller": [
"./pkg-controller/account_wasm.d.ts"
],
"session": [
"./pkg-session/account_wasm.d.ts"
]
}
},
"devDependencies": {
"@cartridge/tsconfig": "workspace:*",
"tsup": "catalog:",
"typescript": "catalog:",
"wasm-pack": "^0.13.0"
}
}
}
6 changes: 5 additions & 1 deletion packages/account-wasm/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use starknet_types_core::felt::Felt;
use url::Url;
use wasm_bindgen::prelude::*;

use crate::errors::JsControllerError;
use crate::types::call::JsCall;
use crate::types::session::Session;
use crate::types::{Felts, JsFelt};
Expand Down Expand Up @@ -137,7 +138,10 @@ impl CartridgeSessionAccount {
Ok(Felts(signature.into_iter().map(JsFelt).collect()))
}

pub async fn execute(&self, calls: Vec<JsCall>) -> Result<JsValue> {
pub async fn execute(
&self,
calls: Vec<JsCall>,
) -> std::result::Result<JsValue, JsControllerError> {
let calls = calls
.into_iter()
.map(TryInto::try_into)
Expand Down
38 changes: 28 additions & 10 deletions packages/controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"types": "dist/index.d.ts",
"type": "module",
"scripts": {
"build:deps": "tsup --dts-resolve",
"build:deps": "tsup",
"build": "pnpm build:deps",
"format": "prettier --write \"src/**/*.ts\"",
"format:check": "prettier --check \"src/**/*.ts\"",
Expand All @@ -16,34 +16,52 @@
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./session": {
"types": "./dist/session/index.d.ts",
"default": "./dist/session/index.js"
"import": "./dist/session/index.js",
"require": "./dist/session/index.cjs"
},
"./session/node": {
"types": "./dist/node/index.d.ts",
"import": "./dist/node/index.js",
"require": "./dist/node/index.cjs"
},
"./provider": {
"types": "./dist/provider/index.d.ts",
"default": "./dist/provider/index.js"
"import": "./dist/provider/index.js"
},
"./types": {
"types": "./dist/types/index.d.ts",
"default": "./dist/types/index.js"
"import": "./dist/types/index.js"
}
},
"tsup": {
"entry": [
"src/**"
"src/index.ts",
"src/controller.ts",
"src/lookup.ts",
"src/session/index.ts",
"src/node/index.ts"
],
"format": [
"esm"
"esm",
"cjs"
],
"splitting": false,
"sourcemap": true,
"clean": true
"clean": true,
"dts": true,
"treeshake": {
"preset": "recommended"
},
"exports": "named"
},
"peerDependencies": {
"starknet": "catalog:"
"starknet": "catalog:",
"open": "^10.1.0"
},
"dependencies": {
"@cartridge/account-wasm": "workspace:*",
Expand All @@ -64,4 +82,4 @@
"tsup": "catalog:",
"typescript": "catalog:"
}
}
}
Loading

0 comments on commit 96a4748

Please sign in to comment.