Loading...
Loading...
Use when integrating or maintaining applications built with keep-starknet-strange/starkzap. Covers StarkSDK setup, onboarding (Signer/Privy/Cartridge), wallet lifecycle, sponsored transactions, ERC20 transfers, staking flows, tx builder batching, examples, tests, and generated presets.
npx skill4agent add keep-starknet-strange/starknet-agentic starkzap-sdkhttps://github.com/keep-starknet-strange/starkzapsrc/sdk.tsStarkSDKsrc/wallet/*src/signer/*StarkSignerPrivySignersrc/tx/*TxTxBuildersrc/erc20/*src/staking/*src/types/*AddressAmounttests/*tests/integration/*examples/webexamples/serverexamples/mobileexamples/flappy-birdscripts/*docs/*mintlify-docs/*skills/starkzap-sdk/references/signer-integration.mdskills/starkzap-sdk/references/sponsored-transactions.mdskills/starkzap-sdk/references/erc20-helpers.mdAmountskills/starkzap-sdk/references/staking-reliability.mdskills/starkzap-sdk/scripts/wallet-execute-example.tsskills/starkzap-sdk/scripts/staking-pool-discovery.tsimport { Account, Contract, RpcProvider } from "starknet";
const provider = await RpcProvider.create({
nodeUrl: process.env.RPC_URL!,
});
const account = new Account({
provider,
address: process.env.ACCOUNT_ADDRESS!,
signer: process.env.PRIVATE_KEY!,
cairoVersion: "1",
});
const contract = new Contract({
abi,
address: process.env.CONTRACT_ADDRESS!,
providerOrAccount: account,
});
await contract.call("balance_of", [account.address]); // read
const tx = await account.execute([
{
contractAddress: process.env.CONTRACT_ADDRESS!,
entrypoint: "do_work",
calldata: [],
},
]);
await provider.waitForTransaction(tx.transaction_hash);// With Starkzap Tx wrapper
const submitted = await wallet.execute(calls, { feeMode: "user_pays" });
const stop = submitted.watch(
({ finality, execution }) => console.log(finality, execution),
{ pollIntervalMs: 5000, timeoutMs: 120000 }
);
// stop(); // call to unsubscribe early| Error Class | Typical Signal | Immediate Recovery |
|---|---|---|
| | Re-check token decimals/symbol, parse from known token preset, avoid mixing token types. |
| | Run |
| timeout, 429, provider mismatch | Retry with backoff, confirm |
| | Run |
| Privy 401/403, invalid signature response | Verify signer server auth, headers/body resolver, and trusted |
skills/starkzap-sdk/references/*skills/starkzap-sdk/scripts/*StarkSDKStarkSDKnetworkrpcUrl + chainIdsdk.onboard(...)sdk.connectWallet(...)wallet.ensureReady({ deploy: "if_needed" })OnboardStrategy.SignerOnboardStrategy.PrivyOnboardStrategy.Cartridgeimport {
ChainId,
OnboardStrategy,
StarkSDK,
StarkSigner,
} from "starkzap";
const sdk = new StarkSDK({ network: "sepolia" });
const customSdk = new StarkSDK({
rpcUrl: process.env.RPC_URL!,
chainId: ChainId.SEPOLIA,
});
const signerResult = await sdk.onboard({
strategy: OnboardStrategy.Signer,
account: { signer: new StarkSigner(process.env.PRIVATE_KEY!) },
feeMode: "user_pays",
deploy: "if_needed",
});
const privyResult = await sdk.onboard({
strategy: OnboardStrategy.Privy,
privy: {
resolve: async () => ({
walletId: process.env.PRIVY_WALLET_ID!,
publicKey: process.env.PRIVY_PUBLIC_KEY!,
serverUrl: process.env.PRIVY_SIGNER_URL!,
}),
},
feeMode: "sponsored",
});
const cartridgeResult = await sdk.onboard({
strategy: OnboardStrategy.Cartridge,
cartridge: {
preset: "controller",
policies: [{ target: "0xPOOL", method: "stake" }],
},
});
const wallet = await sdk.connectWallet({
account: { signer: new StarkSigner(process.env.PRIVATE_KEY!) },
feeMode: "sponsored",
});
await wallet.ensureReady({ deploy: "if_needed" });wallet.executewallet.preflightwallet.txwallet.execute(calls, options)wallet.preflight({ calls, feeMode })wallet.tx()TxBuilderconst calls = [
{
contractAddress: process.env.CONTRACT_ADDRESS!,
entrypoint: "do_work",
calldata: [],
},
];
const preflight = await wallet.preflight({
calls,
feeMode: "user_pays",
});
if (!preflight.ok) {
throw new Error(`Preflight failed: ${preflight.reason}`);
}
const userPaysTx = await wallet.execute(calls, { feeMode: "user_pays" });
await userPaysTx.wait();
const sponsoredTx = await wallet.execute(calls, { feeMode: "sponsored" });
await sponsoredTx.wait();
const batchedTx = await wallet
.tx()
.add(...calls)
.send({ feeMode: "sponsored" });
await batchedTx.wait();function getSdkErrorClass(error: unknown): string {
const message = error instanceof Error ? error.message : String(error);
if (message.includes("not deployed")) return "UNDEPLOYED_ACCOUNT";
if (message.includes("timed out") || message.includes("429")) {
return "RPC_OR_NETWORK";
}
if (message.includes("signature") || message.includes("Privy")) {
return "AUTH_OR_PERMISSION";
}
if (message.includes("Invalid") || message.includes("Amount")) {
return "VALIDATION_ERROR";
}
return "UNKNOWN";
}
try {
await wallet.execute(calls, { feeMode: "user_pays" });
} catch (error) {
const kind = getSdkErrorClass(error);
if (kind === "UNDEPLOYED_ACCOUNT") {
await wallet.ensureReady({ deploy: "if_needed" });
}
throw error;
}OnboardStrategy.Cartridgeuser_payssponsoredAmountimport { Amount } from "starkzap";
const usdcAmount = Amount.parse("25", USDC);
try {
const tx = await wallet
.tx()
.transfer(USDC, [
{ to: recipientA, amount: usdcAmount },
{ to: recipientB, amount: Amount.parse("5", USDC) },
])
.send({ feeMode: "user_pays" });
await tx.wait();
} catch (error) {
// Re-parse Amount from the expected token preset before retrying.
throw error;
}enteraddexit intentexitstarknet-defiexamples/web/main.tsexamples/server/server.tsREADMEsrc/erc20/token/presets.tssrc/erc20/token/presets.sepolia.tssrc/staking/validator/presets.tssrc/staking/validator/presets.sepolia.tsdocs/api/**docs/export/**npm run generate:tokens
npm run generate:tokens:sepolia
npm run generate:validators
npm run generate:validators:sepolia
npm run docs:api
npm run docs:exportsrc/index.tsnpm run typecheck
npm testnpm run build
npm run test:allnpm run test:integration| Error Class | Typical Trigger | Recovery Steps |
|---|---|---|
| | Confirm token decimals/symbol, re-create |
| RPC timeout, | Retry with exponential backoff, check |
| | Run |
| | Increase timeout where appropriate, add abort handling, retry on fresh provider session, avoid parallel heavy queries. |
| Privy signing errors, 401/403, invalid signature payloads | Verify signer server auth headers/body, validate trusted |
| | Run |
| Preset/docs changes diverge from source of truth | Regenerate via |
examples/*src/wallet/index.tssrc/wallet/utils.tstests/wallet*.test.tssrc/signer/privy.tsexamples/server/server.tstests/privy-signer.test.tssrc/staking/staking.tssrc/staking/presets.tstests/integration/staking.test.ts