controller-backend

安装量: 52
排名: #14179

安装

npx skills add https://github.com/cartridge-gg/docs --skill controller-backend

Controller Backend Integration Integrate Controller into server-side applications and automated systems. Sessions enable pre-approved transactions without manual user approval, making them ideal for automated backends. Node.js Uses SessionProvider with file-based session storage. Installation pnpm add @cartridge/controller starknet Setup import SessionProvider , { ControllerError , } from "@cartridge/controller/session/node" ; import { constants } from "starknet" ; import path from "path" ; const ETH_CONTRACT = "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" ; async function main ( ) { const storagePath = process . env . CARTRIDGE_STORAGE_PATH || path . join ( process . cwd ( ) , ".cartridge" ) ; const provider = new SessionProvider ( { rpc : "https://api.cartridge.gg/x/starknet/mainnet" , chainId : constants . StarknetChainId . SN_MAIN , policies : { contracts : { [ ETH_CONTRACT ] : { methods : [ { name : "approve" , entrypoint : "approve" , spender : "0x1234567890abcdef1234567890abcdef12345678" , amount : "0xffffffffffffffffffffffffffffffff" , description : "Approve spending of tokens" , } , { name : "transfer" , entrypoint : "transfer" } , ] , } , } , } , basePath : storagePath , } ) ; try { const account = await provider . connect ( ) ; if ( account ) { console . log ( "Account address:" , account . address ) ; // Example: Transfer ETH const amount = "0x0" ; const recipient = account . address ; // Replace with actual recipient const result = await account . execute ( [ { contractAddress : ETH_CONTRACT , 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 ) ; Notes basePath specifies session storage directory (must be writable) First run requires browser-based session creation Session persists between runs Rust Uses account_sdk crate for native Rust integration. Installation [ dependencies ] account_sdk = { git = "https://github.com/cartridge-gg/controller-rs.git" , package = "account_sdk" } starknet = "0.10" tokio = { version = "1" , features = [ "full" ] } Setup use account_sdk :: { controller :: Controller , signers :: Signer } ; use starknet :: { accounts :: Account , providers :: Provider , signers :: SigningKey , core :: types :: FieldElement , } ; use std :: env ;

[tokio::main]

async
fn
main
(
)
{
// Load private key from environment
let
private_key
=
env
::
var
(
"PRIVATE_KEY"
)
.
expect
(
"PRIVATE_KEY must be set"
)
;
let
owner
=
Signer
::
Starknet
(
SigningKey
::
from_secret_scalar
(
FieldElement
::
from_hex_be
(
&
private_key
)
.
unwrap
(
)
)
)
;
let
rpc_url
=
"https://api.cartridge.gg/x/starknet/mainnet"
;
let
provider
=
Provider
::
try_from
(
rpc_url
)
.
unwrap
(
)
;
let
chain_id
=
provider
.
chain_id
(
)
.
await
.
unwrap
(
)
;
let
controller
=
Controller
::
new
(
"my_app"
.
to_string
(
)
,
"username"
.
to_string
(
)
,
FieldElement
::
from_hex_be
(
"0xCLASS_HASH"
)
.
unwrap
(
)
,
rpc_url
.
parse
(
)
.
unwrap
(
)
,
owner
,
FieldElement
::
from_hex_be
(
"0xCONTROLLER_ADDRESS"
)
.
unwrap
(
)
,
chain_id
,
)
;
// Deploy if needed
controller
.
deploy
(
)
.
await
.
unwrap
(
)
;
// Execute transaction
let
call
=
starknet
::
core
::
types
::
FunctionCall
{
contract_address
:
FieldElement
::
from_hex_be
(
"0xCONTRACT"
)
.
unwrap
(
)
,
entry_point_selector
:
starknet
::
core
::
utils
::
get_selector_from_name
(
"transfer"
)
.
unwrap
(
)
,
calldata
:
vec!
[
FieldElement
::
from
(
123
)
]
,
}
;
controller
.
execute
(
vec!
[
call
]
,
None
)
.
await
.
unwrap
(
)
;
}
Headless Controller
For server-side execution with custom signing keys.
Use Cases
Single owner, multiple accounts
Automated game backends (bots, NPCs)
Custom key management requirements
C++ Example
Warning
Never commit private keys. Use environment variables or secret managers.

include "controller.hpp"

include int main ( ) { // Load from environment - NEVER hardcode! const char * pk = std :: getenv ( "PRIVATE_KEY" ) ; if ( ! pk ) { std :: cerr << "PRIVATE_KEY not set" << std :: endl ; return 1 ; } std :: string private_key ( pk ) ; auto owner = controller :: Owner :: init ( private_key ) ; auto ctrl = controller :: Controller :: new_headless ( "my_app" , "bot_account" , controller :: get_controller_class_hash ( controller :: Version :: kLatest ) , "https://api.cartridge.gg/x/starknet/mainnet" , owner , "0x534e5f4d41494e" // SN_MAIN ) ; // Register new account onchain ctrl -> signup ( controller :: SignerType :: kStarknet , std :: nullopt , std :: nullopt ) ; // Execute transaction controller :: Call call { "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" , "transfer" , { "0xRECIPIENT" , "0x100" , "0x0" } } ; std :: string tx_hash = ctrl -> execute ( { call } ) ; std :: cout << "Transaction: " << tx_hash << std :: endl ; return 0 ; } Security Best Practices Never commit private keys . Use: Environment variables Secret managers (AWS Secrets Manager, HashiCorp Vault) Hardware security modules (HSM) // Good const privateKey = process . env . PRIVATE_KEY ; // Bad - NEVER do this const privateKey = "0x1234..." ; Telegram Mini-Apps Use SessionConnector with Telegram WebApp context. Integration Flow Configure session policies Set up SessionProvider with cloud storage Handle authentication redirects Execute transactions via session Setup import { SessionConnector } from "@cartridge/connector" ; import { constants } from "starknet" ; const policies = { contracts : { "0x..." : { methods : [ { name : "action" , entrypoint : "action" } ] , } , } , } ; const connector = new SessionConnector ( { policies , rpc : "https://api.cartridge.gg/x/starknet/mainnet" , chainId : constants . StarknetChainId . SN_MAIN , redirectUrl : window . Telegram ?. WebApp ?. initData ? "https://t.me/MyBot/app" : "https://myapp.com/callback" , } ) ; Next.js WebAssembly Configuration For Telegram mini-apps using Next.js: // next.config.js module . exports = { webpack : ( config ) => { config . experiments = { ... config . experiments , asyncWebAssembly : true , } ; return config ; } , } ;

返回排行榜