Monitor 10 Wallets
Canonical HTTP, SDK, and CLI starter for monitoring a fixed wallet set with recent activity, transactions, holdings, and token flows.
Canonical HTTP, SDK, and CLI starter for monitoring a fixed wallet set with recent activity, transactions, holdings, and token flows.
Use this guide when your job is not “explore one address” but “keep a fixed set of wallets under watch.”
This is the canonical public starter for that workflow across:
export MEZCAL_BASE_URL="https://<your-mezcal-host>/api"
export MEZCAL_API_KEY="mzk_live_your_key_here"
export MEZCAL_CHAIN="SN_MAIN"
export MEZCAL_WATCHED_WALLETS="0xwalletA,0xwalletB,0xwalletC,0xwalletD,0xwalletE,0xwalletF,0xwalletG,0xwalletH,0xwalletI,0xwalletJ"
export MEZCAL_WATCHED_TOKENS="0xstrkToken,0xethToken,0xusdcToken"
export MEZCAL_ACTIVITY_LIMIT="50"
export MEZCAL_TRANSACTION_LIMIT="50"
export MEZCAL_TRANSFER_LIMIT="100"
MEZCAL_BASE_URL should already include /api for hosted external access.
All examples below then call the normal /v1/* routes relative to that base.
Use this first when you are driving Starkscan from an editor with .http support and you want to see the exact request and response contract before you automate loops.
Save this as monitor-wallets.http:
@mezcal = https://<your-mezcal-host>/api
@chain = SN_MAIN
@apiKey = mzk_live_your_key_here
@wallet = 0xwalletA
@token = 0xstrkToken
@activityLimit = 50
@transactionLimit = 50
@transferLimit = 100
GET {{mezcal}}/v1/{{chain}}/address/{{wallet}}/activity?limit={{activityLimit}}
X-Starkscan-Api-Key: {{apiKey}}
###
GET {{mezcal}}/v1/{{chain}}/address/{{wallet}}/transactions?limit={{transactionLimit}}
X-Starkscan-Api-Key: {{apiKey}}
###
GET {{mezcal}}/v1/{{chain}}/address/{{wallet}}/token-holdings
X-Starkscan-Api-Key: {{apiKey}}
###
GET {{mezcal}}/v1/{{chain}}/token/{{token}}/transfers?address={{wallet}}&limit={{transferLimit}}
X-Starkscan-Api-Key: {{apiKey}}
Duplicate the request blocks per wallet or token when you need a small fixed watch set from the editor. If you need shell loops and JSON files on disk, use the shell starter below.
Use this when you want zero-install shell automation and local JSON artifacts.
OUTPUT_DIR="${OUTPUT_DIR:-./mezcal-wallet-monitor-rest}"
mkdir -p "$OUTPUT_DIR"
IFS=',' read -r -a MEZCAL_WALLETS <<< "$MEZCAL_WATCHED_WALLETS"
IFS=',' read -r -a MEZCAL_TOKENS <<< "$MEZCAL_WATCHED_TOKENS"
for wallet in "${MEZCAL_WALLETS[@]}"; do
wallet="$(printf '%s' "$wallet" | xargs)"
curl -sS \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/$MEZCAL_CHAIN/address/$wallet/activity?limit=$MEZCAL_ACTIVITY_LIMIT" \
> "$OUTPUT_DIR/${wallet}.activity.json"
curl -sS \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/$MEZCAL_CHAIN/address/$wallet/transactions?limit=$MEZCAL_TRANSACTION_LIMIT" \
> "$OUTPUT_DIR/${wallet}.transactions.json"
curl -sS \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/$MEZCAL_CHAIN/address/$wallet/token-holdings" \
> "$OUTPUT_DIR/${wallet}.holdings.json"
done
for token in "${MEZCAL_TOKENS[@]}"; do
token="$(printf '%s' "$token" | xargs)"
url="$MEZCAL_BASE_URL/v1/$MEZCAL_CHAIN/token/$token/transfers?limit=$MEZCAL_TRANSFER_LIMIT"
for wallet in "${MEZCAL_WALLETS[@]}"; do
wallet="$(printf '%s' "$wallet" | xargs)"
url="${url}&address=${wallet}"
done
curl -sS \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$url" \
> "$OUTPUT_DIR/${token}.transfers.json"
done
Only move to the SDK when this workflow belongs inside application code. If you are still validating routes, auth, or payloads, stay on one of the HTTP starters above.
Save this as monitor-wallets.ts:
import { mkdir, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { createStarkscanClient } from '@mezcal/sdk';
function requiredEnv(name: string): string {
const value = process.env[name]?.trim();
if (!value) throw new Error(`${name} is required`);
return value;
}
function csvEnv(name: string): string[] {
return requiredEnv(name)
.split(',')
.map((value) => value.trim())
.filter(Boolean);
}
const baseUrl = requiredEnv('MEZCAL_BASE_URL');
const apiKey = requiredEnv('MEZCAL_API_KEY');
const chainId = process.env.MEZCAL_CHAIN?.trim() || 'SN_MAIN';
const wallets = csvEnv('MEZCAL_WATCHED_WALLETS');
const tokens = csvEnv('MEZCAL_WATCHED_TOKENS');
const activityLimit = Number(process.env.MEZCAL_ACTIVITY_LIMIT || '50');
const transactionLimit = Number(process.env.MEZCAL_TRANSACTION_LIMIT || '50');
const transferLimit = Number(process.env.MEZCAL_TRANSFER_LIMIT || '100');
const outputDir = process.env.MEZCAL_OUTPUT_DIR?.trim() || './mezcal-wallet-monitor-sdk';
const mezcal = createStarkscanClient({ apiKey, baseUrl, chainId });
await mkdir(outputDir, { recursive: true });
for (const wallet of wallets) {
const [activity, transactions, holdings] = await Promise.all([
mezcal.addressActivity(wallet, undefined, activityLimit),
mezcal.addressTransactions(wallet, undefined, transactionLimit),
mezcal.addressTokenHoldings(wallet),
]);
await writeFile(join(outputDir, `${wallet}.activity.json`), JSON.stringify(activity, null, 2));
await writeFile(
join(outputDir, `${wallet}.transactions.json`),
JSON.stringify(transactions, null, 2),
);
await writeFile(join(outputDir, `${wallet}.holdings.json`), JSON.stringify(holdings, null, 2));
}
for (const token of tokens) {
const transfers = await mezcal.tokenTransfers(token, {
addresses: wallets,
limit: transferLimit,
});
await writeFile(
join(outputDir, `${token}.transfers.json`),
JSON.stringify(transfers, null, 2),
);
}
Run it with:
npm install @mezcal/sdk@alpha
bun run ./monitor-wallets.ts
If you need a single typed summary layer, derive it from the activity, transactions, holdings, and filtered transfer reads above rather than depending on an unpublished batch helper.
Use that only as a top-level summary. Keep the activity, transactions, holdings, and transfer calls for the full monitoring view.
Use the CLI when you want repeatable shell commands, local JSON files, and no app code.
OUTPUT_DIR="${OUTPUT_DIR:-./mezcal-wallet-monitor-cli}"
mkdir -p "$OUTPUT_DIR"
IFS=',' read -r -a MEZCAL_WALLETS <<< "$MEZCAL_WATCHED_WALLETS"
IFS=',' read -r -a MEZCAL_TOKENS <<< "$MEZCAL_WATCHED_TOKENS"
for wallet in "${MEZCAL_WALLETS[@]}"; do
wallet="$(printf '%s' "$wallet" | xargs)"
mezcal --output-format json address-activity "$wallet" --limit "$MEZCAL_ACTIVITY_LIMIT" \
> "$OUTPUT_DIR/${wallet}.activity.json"
mezcal --output-format json address-transactions "$wallet" --limit "$MEZCAL_TRANSACTION_LIMIT" \
> "$OUTPUT_DIR/${wallet}.transactions.json"
mezcal --output-format json address-token-holdings "$wallet" \
> "$OUTPUT_DIR/${wallet}.holdings.json"
done
for token in "${MEZCAL_TOKENS[@]}"; do
token="$(printf '%s' "$token" | xargs)"
transfer_args=()
for wallet in "${MEZCAL_WALLETS[@]}"; do
wallet="$(printf '%s' "$wallet" | xargs)"
transfer_args+=(--address "$wallet")
done
mezcal --output-format json token-transfers "$token" \
"${transfer_args[@]}" \
--limit "$MEZCAL_TRANSFER_LIMIT" \
> "$OUTPUT_DIR/${token}.transfers.json"
done
If your workflow needs a single shell sanity check before the full loop:
mezcal status
mezcal address-activity "$(printf '%s' "$MEZCAL_WATCHED_WALLETS" | cut -d',' -f1)" --limit 10