Skip to content

Instantly share code, notes, and snippets.

@mgild
Created October 6, 2025 03:14
Show Gist options
  • Save mgild/63bd892db33802d694e14cabd2dce0b7 to your computer and use it in GitHub Desktop.
Save mgild/63bd892db33802d694e14cabd2dce0b7 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bun
import { CrossbarClient } from "@switchboard-xyz/common";
import * as fs from 'fs';
import * as crypto from 'crypto';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
interface Arguments {
apiKeyId: string;
privateKeyPath: string;
crossbarUrl: string;
orderId?: string;
}
const argv = yargs(hideBin(process.argv))
.option('api-key-id', {
alias: 'k',
type: 'string',
description: 'Kalshi API Key ID',
demandOption: true
})
.option('private-key-path', {
alias: 'p',
type: 'string',
description: 'Path to the private key PEM file',
demandOption: true
})
.option('order-id', {
alias: 'o',
type: 'string',
description: 'Order ID to fetch (if not provided, lists all orders)',
demandOption: false
})
.option('crossbar-url', {
alias: 'u',
type: 'string',
description: 'Crossbar server URL',
default: 'https://crossbar.switchboardlabs.xyz'
})
.example('$0 -k <api-key-id> -p /path/to/key.pem', 'List all orders')
.example('$0 -k <api-key-id> -p /path/to/key.pem -o <order-id>', 'Get specific order')
.help()
.alias('help', 'h')
.parseSync() as Arguments;
function validatePrivateKeyPath(keyPath: string): void {
if (!fs.existsSync(keyPath)) {
throw new Error(`Private key file not found: ${keyPath}`);
}
}
function loadPrivateKey(keyPath: string): crypto.KeyObject {
const privateKeyPem = fs.readFileSync(keyPath, 'utf8');
return crypto.createPrivateKey(privateKeyPem);
}
function createSignature(
privateKey: crypto.KeyObject,
timestamp: string,
method: string,
path: string
): string {
const message = `${timestamp}${method}${path}`;
const messageBuffer = Buffer.from(message, "utf8");
const signature = crypto.sign("sha256", messageBuffer, {
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST,
});
return signature.toString("base64");
}
(async function main() {
try {
validatePrivateKeyPath(argv.privateKeyPath);
const privateKey = loadPrivateKey(argv.privateKeyPath);
const timestamp = Date.now().toString();
const method = 'GET';
const isListOrders = !argv.orderId;
const path = isListOrders
? '/trade-api/v2/portfolio/orders'
: `/trade-api/v2/portfolio/orders/${argv.orderId}`;
const signature = createSignature(privateKey, timestamp, method, path);
if (isListOrders) {
console.log('πŸ“‹ Listing Orders');
console.log('=================\n');
const url = `https://api.elections.kalshi.com${path}`;
const response = await fetch(url, {
method: 'GET',
headers: {
'KALSHI-ACCESS-KEY': argv.apiKeyId,
'KALSHI-ACCESS-SIGNATURE': signature,
'KALSHI-ACCESS-TIMESTAMP': timestamp
}
});
if (!response.ok) {
throw new Error(`API request failed: ${response.status} ${response.statusText}`);
}
const data = await response.json();
console.log('Orders:');
console.log(JSON.stringify(data, null, 2));
return;
}
const url = `https://api.elections.kalshi.com${path}`;
console.log('🎯 Kalshi Job Testing via Crossbar');
console.log('===================================\n');
console.log('πŸ“‹ Configuration:');
console.log(`πŸ”‘ API Key ID: ${argv.apiKeyId}`);
console.log(`πŸ“‹ Order ID: ${argv.orderId}`);
console.log(`⏰ Timestamp: ${timestamp}`);
console.log(`✍️ Signature: ${signature.substring(0, 50)}...${signature.substring(signature.length - 20)}`);
console.log(`🌐 Crossbar URL: ${argv.crossbarUrl}\n`);
const crossbar = new CrossbarClient(argv.crossbarUrl);
console.log('πŸš€ Simulating Kalshi get-order job via Crossbar...\n');
const simulation = await crossbar.simulateJobs({
jobs: [
{
tasks: [
{
kalshiApiTask: {
url,
apiKeyId: argv.apiKeyId,
signature: "${KALSHI_SIGNATURE}",
timestamp: "${KALSHI_TIMESTAMP}"
}
},
{
jsonParseTask: {
path: "$.order.yes_price_dollars",
}
}
]
}
],
includeReceipts: true,
variableOverrides: {
KALSHI_SIGNATURE: signature,
KALSHI_TIMESTAMP: timestamp
}
});
console.log('βœ… Success! Simulation Result:');
console.log('==============================');
console.log(JSON.stringify(simulation, null, 2));
} catch (error) {
console.error('❌ Error:', error);
if (error instanceof Error) {
console.error('Message:', error.message);
if (error.stack) {
console.error('Stack:', error.stack);
}
}
process.exit(1);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment