@blockrun/cc 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +63 -0
- package/README.md +183 -0
- package/dist/commands/balance.d.ts +1 -0
- package/dist/commands/balance.js +18 -0
- package/dist/commands/setup.d.ts +1 -0
- package/dist/commands/setup.js +19 -0
- package/dist/commands/start.d.ts +6 -0
- package/dist/commands/start.js +61 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +25 -0
- package/dist/proxy/server.d.ts +6 -0
- package/dist/proxy/server.js +106 -0
- package/dist/wallet/manager.d.ts +6 -0
- package/dist/wallet/manager.js +15 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
Licensor: BlockRun AI (Piebald LLC)
|
|
4
|
+
|
|
5
|
+
Licensed Work: brcc
|
|
6
|
+
|
|
7
|
+
Change Date: 2030-03-23
|
|
8
|
+
|
|
9
|
+
Change License: MIT
|
|
10
|
+
|
|
11
|
+
Parameters:
|
|
12
|
+
Additional Use Grant: You may use the Licensed Work for any purpose,
|
|
13
|
+
including production use, provided that you do not offer the Licensed
|
|
14
|
+
Work as a commercial hosted service that competes with BlockRun's
|
|
15
|
+
paid offerings.
|
|
16
|
+
|
|
17
|
+
Notice:
|
|
18
|
+
The Business Source License (this document, or the "License") is not
|
|
19
|
+
an Open Source license. However, the Licensed Work will eventually be
|
|
20
|
+
made available under an Open Source License, as stated in this License.
|
|
21
|
+
|
|
22
|
+
Terms:
|
|
23
|
+
|
|
24
|
+
The Licensor hereby grants you the right to copy, modify, create
|
|
25
|
+
derivative works, redistribute, and make non-production use of the
|
|
26
|
+
Licensed Work. The Licensor may make an Additional Use Grant, above,
|
|
27
|
+
permitting limited production use.
|
|
28
|
+
|
|
29
|
+
Effective on the Change Date, or the fourth anniversary of the first
|
|
30
|
+
publicly available distribution of a specific version of the Licensed
|
|
31
|
+
Work under this License, whichever comes first, the Licensor hereby
|
|
32
|
+
grants you rights under the terms of the Change License, and the
|
|
33
|
+
rights granted in the paragraph above terminate.
|
|
34
|
+
|
|
35
|
+
If your use of the Licensed Work does not comply with the requirements
|
|
36
|
+
currently in effect as described in this License, you must purchase a
|
|
37
|
+
commercial license from the Licensor, its affiliated entities, or
|
|
38
|
+
authorized resellers, or you must refrain from using the Licensed Work.
|
|
39
|
+
|
|
40
|
+
All copies of the original and modified Licensed Work, and derivative
|
|
41
|
+
works of the Licensed Work, are subject to this License. This License
|
|
42
|
+
applies separately for each version of the Licensed Work and the
|
|
43
|
+
Change Date may vary for each version of the Licensed Work released by
|
|
44
|
+
Licensor.
|
|
45
|
+
|
|
46
|
+
You must conspicuously display this License on each original or
|
|
47
|
+
modified copy of the Licensed Work. If you receive the Licensed Work
|
|
48
|
+
in original or modified form from a third party, the terms and
|
|
49
|
+
conditions set forth in this License apply to your use of that work.
|
|
50
|
+
|
|
51
|
+
Any use of the Licensed Work in violation of this License will
|
|
52
|
+
automatically terminate your rights under this License for the current
|
|
53
|
+
and all other versions of the Licensed Work.
|
|
54
|
+
|
|
55
|
+
This License does not grant you any right in any trademark or logo of
|
|
56
|
+
Licensor or its affiliates (provided that you may use a trademark or
|
|
57
|
+
logo of Licensor as expressly required by this License).
|
|
58
|
+
|
|
59
|
+
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS
|
|
60
|
+
PROVIDED ON AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES
|
|
61
|
+
AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION)
|
|
62
|
+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
|
|
63
|
+
NON-INFRINGEMENT, AND TITLE.
|
package/README.md
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# brcc
|
|
2
|
+
|
|
3
|
+
**Run Claude Code without rate limits.**
|
|
4
|
+
|
|
5
|
+
Hitting usage limits? Account disabled? Can't verify your phone? brcc fixes all of that.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g brcc
|
|
9
|
+
brcc start
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
One command. No Anthropic account needed. No rate limits. No phone verification. Just USDC.
|
|
13
|
+
|
|
14
|
+
## The Problem
|
|
15
|
+
|
|
16
|
+
Claude Code users hit these walls daily ([4,350+ GitHub issue comments](https://github.com/anthropics/claude-code/issues)):
|
|
17
|
+
|
|
18
|
+
- **"Instantly hitting usage limits with Max subscription"** — 1,252 comments
|
|
19
|
+
- **"Account disabled after payment"** — 145 comments
|
|
20
|
+
- **"Phone verification — unable to send code"** — 546 comments
|
|
21
|
+
- **"5-hour limit reached in less than 1h30"** — 108 comments
|
|
22
|
+
- **"Rate limit reached despite Max subscription"** — 89 comments
|
|
23
|
+
|
|
24
|
+
## The Fix
|
|
25
|
+
|
|
26
|
+
brcc routes Claude Code through [BlockRun](https://blockrun.ai), a pay-per-use AI gateway. You pay exactly what you use — no subscriptions, no limits, no accounts.
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Claude Code --> brcc (local proxy) --> BlockRun API --> Any model
|
|
30
|
+
auto-signs payments 40+ models GPT-5, Claude, Gemini, ...
|
|
31
|
+
with your wallet pay per token
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Install
|
|
38
|
+
npm install -g brcc
|
|
39
|
+
|
|
40
|
+
# Create a wallet (one time)
|
|
41
|
+
brcc setup
|
|
42
|
+
# -> Wallet created: 0xCC8c...5EF8
|
|
43
|
+
# -> Send USDC on Base to this address
|
|
44
|
+
|
|
45
|
+
# Fund your wallet
|
|
46
|
+
# Send $5-10 USDC on Base chain to your wallet address
|
|
47
|
+
# Buy USDC on Coinbase, send directly to your address
|
|
48
|
+
|
|
49
|
+
# Launch Claude Code
|
|
50
|
+
brcc start
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
That's it. Claude Code opens with access to 40+ models, no rate limits.
|
|
54
|
+
|
|
55
|
+
## What $5 Gets You
|
|
56
|
+
|
|
57
|
+
| Model | ~Requests per $5 | Best For |
|
|
58
|
+
|-------|-------------------|----------|
|
|
59
|
+
| Claude Sonnet 4.6 | ~100 | Coding (default) |
|
|
60
|
+
| GPT-5.4 | ~80 | Reasoning |
|
|
61
|
+
| Claude Haiku 4.5 | ~500 | Fast tasks |
|
|
62
|
+
| DeepSeek V3 | ~5,000 | Budget coding |
|
|
63
|
+
| GPT-OSS 120B | Unlimited | Free tier |
|
|
64
|
+
|
|
65
|
+
## Why brcc vs Claude Max Subscription
|
|
66
|
+
|
|
67
|
+
| | Claude Max ($100-200/mo) | brcc |
|
|
68
|
+
|--|--------------------------|------|
|
|
69
|
+
| **Rate limits** | Constantly hit | None |
|
|
70
|
+
| **Account locks** | Common | Impossible — no account |
|
|
71
|
+
| **Phone verification** | Required | Not needed |
|
|
72
|
+
| **Pricing** | Opaque, subscription | Transparent, pay-per-token |
|
|
73
|
+
| **Region restrictions** | Some countries blocked | Works everywhere |
|
|
74
|
+
| **Models** | Claude only | 40+ models (GPT, Gemini, DeepSeek...) |
|
|
75
|
+
| **Monthly cost** | $100-200 fixed | $5-50 based on usage |
|
|
76
|
+
| **Auth issues** | OAuth, API key conflicts | Wallet = identity |
|
|
77
|
+
|
|
78
|
+
## Commands
|
|
79
|
+
|
|
80
|
+
### `brcc setup`
|
|
81
|
+
|
|
82
|
+
Creates a wallet and shows the address for funding.
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
$ brcc setup
|
|
86
|
+
Wallet created!
|
|
87
|
+
Address: 0xCC8c44AD3dc2A58D841c3EB26131E49b22665EF8
|
|
88
|
+
Send USDC on Base to this address to fund your account.
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Your wallet is saved to `~/.blockrun/` and shared with all BlockRun tools.
|
|
92
|
+
|
|
93
|
+
### `brcc start`
|
|
94
|
+
|
|
95
|
+
Starts the payment proxy and launches Claude Code.
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
$ brcc start
|
|
99
|
+
brcc — BlockRun Claude Code
|
|
100
|
+
|
|
101
|
+
Wallet: 0xCC8c...5EF8
|
|
102
|
+
Proxy: http://localhost:8402
|
|
103
|
+
Backend: https://blockrun.ai/api
|
|
104
|
+
|
|
105
|
+
Starting Claude Code...
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Options:
|
|
109
|
+
```bash
|
|
110
|
+
brcc start # Start proxy + launch Claude Code
|
|
111
|
+
brcc start --no-launch # Proxy only (for manual Claude Code setup)
|
|
112
|
+
brcc start -p 9000 # Custom port
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### `brcc balance`
|
|
116
|
+
|
|
117
|
+
Check your USDC balance.
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
$ brcc balance
|
|
121
|
+
Wallet: 0xCC8c44AD3dc2A58D841c3EB26131E49b22665EF8
|
|
122
|
+
USDC Balance: $4.17
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## How It Works
|
|
126
|
+
|
|
127
|
+
1. `brcc start` launches a local HTTP proxy on port 8402
|
|
128
|
+
2. Claude Code connects to the proxy (via `ANTHROPIC_BASE_URL`)
|
|
129
|
+
3. When Claude Code makes an API request, the proxy forwards it to BlockRun
|
|
130
|
+
4. If payment is needed, the proxy automatically signs a USDC micropayment
|
|
131
|
+
5. BlockRun processes the request and returns the response
|
|
132
|
+
6. Claude Code gets the response as normal
|
|
133
|
+
|
|
134
|
+
Your private key never leaves your machine. Only payment signatures are sent.
|
|
135
|
+
|
|
136
|
+
## Funding Your Wallet
|
|
137
|
+
|
|
138
|
+
brcc uses USDC on Base (Coinbase's L2 chain). To fund:
|
|
139
|
+
|
|
140
|
+
1. **Buy USDC** on [Coinbase](https://coinbase.com), [Binance](https://binance.com), or any exchange
|
|
141
|
+
2. **Send USDC** to your brcc wallet address (shown in `brcc setup`)
|
|
142
|
+
3. **Make sure it's on Base chain** — not Ethereum mainnet
|
|
143
|
+
|
|
144
|
+
Typical cost: $0.001-0.05 per Claude Code interaction. $5 lasts most developers a week.
|
|
145
|
+
|
|
146
|
+
## Available Models
|
|
147
|
+
|
|
148
|
+
All [BlockRun models](https://blockrun.ai) work through brcc:
|
|
149
|
+
|
|
150
|
+
- **OpenAI**: GPT-5.4, GPT-5.2, GPT-5-mini, o3, o4-mini
|
|
151
|
+
- **Anthropic**: Claude Opus 4.6, Sonnet 4.6, Haiku 4.5
|
|
152
|
+
- **Google**: Gemini 3.1 Pro, 2.5 Pro, 2.5 Flash
|
|
153
|
+
- **DeepSeek**: V3, Reasoner
|
|
154
|
+
- **xAI**: Grok 3, Grok 4
|
|
155
|
+
- **Free**: NVIDIA GPT-OSS 120B (no payment needed)
|
|
156
|
+
|
|
157
|
+
## FAQ
|
|
158
|
+
|
|
159
|
+
**Q: Is this legal?**
|
|
160
|
+
A: Yes. brcc is an API proxy. You're using Claude Code (Anthropic's open CLI) with a different API backend. OpenRouter, LiteLLM, and others do the same thing. No Anthropic terms are violated because no Anthropic services are used.
|
|
161
|
+
|
|
162
|
+
**Q: Do I need an Anthropic account?**
|
|
163
|
+
A: No. brcc bypasses Anthropic entirely. You don't need an Anthropic account, API key, or subscription.
|
|
164
|
+
|
|
165
|
+
**Q: Is my wallet safe?**
|
|
166
|
+
A: Your private key stays on your machine (`~/.blockrun/.session`, chmod 600). It's only used for local signing — never transmitted over the network.
|
|
167
|
+
|
|
168
|
+
**Q: What if BlockRun goes down?**
|
|
169
|
+
A: Your wallet and funds are yours on-chain. USDC is always withdrawable regardless of BlockRun's status.
|
|
170
|
+
|
|
171
|
+
**Q: Can I use models other than Claude?**
|
|
172
|
+
A: Yes. Claude Code works with any model that speaks the Anthropic Messages API format. Through brcc, you can use GPT-5, Gemini, DeepSeek, and 30+ other models.
|
|
173
|
+
|
|
174
|
+
## Links
|
|
175
|
+
|
|
176
|
+
- [BlockRun](https://blockrun.ai) — The AI gateway powering brcc
|
|
177
|
+
- [BlockRun TypeScript SDK](https://www.npmjs.com/package/@blockrun/llm)
|
|
178
|
+
- [Telegram](https://t.me/+mroQv4-4hGgzOGUx)
|
|
179
|
+
- [GitHub Issues](https://github.com/BlockRunAI/brcc/issues)
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
[Business Source License 1.1](LICENSE) — Free to use, modify, and deploy. Cannot be used to build a competing hosted service. Converts to MIT in 2030.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function balanceCommand(): Promise<void>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { setupAgentWallet } from '@blockrun/llm';
|
|
3
|
+
export async function balanceCommand() {
|
|
4
|
+
try {
|
|
5
|
+
const client = setupAgentWallet({ silent: true });
|
|
6
|
+
const address = client.getWalletAddress();
|
|
7
|
+
const balance = await client.getBalance();
|
|
8
|
+
console.log(`Wallet: ${chalk.cyan(address)}`);
|
|
9
|
+
console.log(`USDC Balance: ${chalk.green(`$${balance.toFixed(2)}`)}`);
|
|
10
|
+
if (balance === 0) {
|
|
11
|
+
console.log(chalk.dim(`\nSend USDC on Base to ${address} to get started.`));
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
console.log(chalk.red('No wallet found. Run `brcc setup` first.'));
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupCommand(): Promise<void>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { getOrCreateWallet, scanWallets } from '@blockrun/llm';
|
|
3
|
+
export async function setupCommand() {
|
|
4
|
+
const wallets = scanWallets();
|
|
5
|
+
if (wallets.length > 0) {
|
|
6
|
+
console.log(chalk.yellow('Wallet already exists.'));
|
|
7
|
+
console.log(`Address: ${chalk.cyan(wallets[0].address)}`);
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
console.log('Creating new wallet...\n');
|
|
11
|
+
const { address, isNew } = getOrCreateWallet();
|
|
12
|
+
if (isNew) {
|
|
13
|
+
console.log(chalk.green('Wallet created!\n'));
|
|
14
|
+
}
|
|
15
|
+
console.log(`Address: ${chalk.cyan(address)}`);
|
|
16
|
+
console.log(`\nSend USDC on Base to this address to fund your account.`);
|
|
17
|
+
console.log(`Then run ${chalk.bold('brcc start')} to launch Claude Code.\n`);
|
|
18
|
+
console.log(chalk.dim('Wallet saved to ~/.blockrun/'));
|
|
19
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { getOrCreateWallet } from '@blockrun/llm';
|
|
4
|
+
import { createProxy } from '../proxy/server.js';
|
|
5
|
+
import { DEFAULT_API_URL, DEFAULT_PROXY_PORT } from '../config.js';
|
|
6
|
+
export async function startCommand(options) {
|
|
7
|
+
const wallet = getOrCreateWallet();
|
|
8
|
+
if (wallet.isNew) {
|
|
9
|
+
console.log(chalk.yellow('No wallet found — created a new one.'));
|
|
10
|
+
console.log(`Address: ${chalk.cyan(wallet.address)}`);
|
|
11
|
+
console.log(`\nSend USDC on Base to this address, then run ${chalk.bold('brcc start')} again.\n`);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const port = parseInt(options.port || String(DEFAULT_PROXY_PORT));
|
|
15
|
+
const shouldLaunch = options.launch !== false;
|
|
16
|
+
console.log(chalk.bold('brcc — BlockRun Claude Code\n'));
|
|
17
|
+
console.log(`Wallet: ${chalk.cyan(wallet.address)}`);
|
|
18
|
+
console.log(`Proxy: ${chalk.cyan(`http://localhost:${port}`)}`);
|
|
19
|
+
console.log(`Backend: ${chalk.dim(DEFAULT_API_URL)}\n`);
|
|
20
|
+
const server = createProxy({ port, apiUrl: DEFAULT_API_URL });
|
|
21
|
+
server.listen(port, () => {
|
|
22
|
+
console.log(chalk.green(`Proxy running on port ${port}\n`));
|
|
23
|
+
if (shouldLaunch) {
|
|
24
|
+
console.log('Starting Claude Code...\n');
|
|
25
|
+
const claude = spawn('claude', [], {
|
|
26
|
+
stdio: 'inherit',
|
|
27
|
+
env: {
|
|
28
|
+
...process.env,
|
|
29
|
+
ANTHROPIC_BASE_URL: `http://localhost:${port}/api`,
|
|
30
|
+
ANTHROPIC_API_KEY: 'brcc',
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
claude.on('error', (err) => {
|
|
34
|
+
if (err.code === 'ENOENT') {
|
|
35
|
+
console.log(chalk.red('\nClaude Code not found. Install it first:'));
|
|
36
|
+
console.log(chalk.dim(' npm install -g @anthropic-ai/claude-code'));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
console.error('Failed to start Claude Code:', err.message);
|
|
40
|
+
}
|
|
41
|
+
server.close();
|
|
42
|
+
process.exit(1);
|
|
43
|
+
});
|
|
44
|
+
claude.on('exit', (code) => {
|
|
45
|
+
server.close();
|
|
46
|
+
process.exit(code ?? 0);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
console.log('Proxy-only mode. Set this in your shell:\n');
|
|
51
|
+
console.log(chalk.bold(` export ANTHROPIC_BASE_URL=http://localhost:${port}/api`));
|
|
52
|
+
console.log(chalk.bold(` export ANTHROPIC_API_KEY=brcc`));
|
|
53
|
+
console.log(`\nThen run ${chalk.bold('claude')} in another terminal.`);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
process.on('SIGINT', () => {
|
|
57
|
+
console.log('\nShutting down...');
|
|
58
|
+
server.close();
|
|
59
|
+
process.exit(0);
|
|
60
|
+
});
|
|
61
|
+
}
|
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { setupCommand } from './commands/setup.js';
|
|
4
|
+
import { startCommand } from './commands/start.js';
|
|
5
|
+
import { balanceCommand } from './commands/balance.js';
|
|
6
|
+
const program = new Command();
|
|
7
|
+
program
|
|
8
|
+
.name('brcc')
|
|
9
|
+
.description('BlockRun Claude Code — run Claude Code with any model, pay with USDC')
|
|
10
|
+
.version('0.1.0');
|
|
11
|
+
program
|
|
12
|
+
.command('setup')
|
|
13
|
+
.description('Create a new wallet for payments')
|
|
14
|
+
.action(setupCommand);
|
|
15
|
+
program
|
|
16
|
+
.command('start')
|
|
17
|
+
.description('Start proxy and launch Claude Code')
|
|
18
|
+
.option('-p, --port <port>', 'Proxy port', '8402')
|
|
19
|
+
.option('--no-launch', 'Start proxy only, do not launch Claude Code')
|
|
20
|
+
.action(startCommand);
|
|
21
|
+
program
|
|
22
|
+
.command('balance')
|
|
23
|
+
.description('Check wallet USDC balance')
|
|
24
|
+
.action(balanceCommand);
|
|
25
|
+
program.parse();
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import http from 'node:http';
|
|
2
|
+
import { getOrCreateWallet, createPaymentPayload, parsePaymentRequired, extractPaymentDetails, } from '@blockrun/llm';
|
|
3
|
+
export function createProxy(options) {
|
|
4
|
+
const wallet = getOrCreateWallet();
|
|
5
|
+
const privateKey = wallet.privateKey;
|
|
6
|
+
const fromAddress = wallet.address;
|
|
7
|
+
const server = http.createServer(async (req, res) => {
|
|
8
|
+
if (req.method === 'OPTIONS') {
|
|
9
|
+
res.writeHead(200);
|
|
10
|
+
res.end();
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const path = req.url?.replace(/^\/api/, '') || '';
|
|
14
|
+
const targetUrl = `${options.apiUrl}${path}`;
|
|
15
|
+
let body = '';
|
|
16
|
+
req.on('data', (chunk) => {
|
|
17
|
+
body += chunk;
|
|
18
|
+
});
|
|
19
|
+
req.on('end', async () => {
|
|
20
|
+
try {
|
|
21
|
+
const headers = {
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
};
|
|
24
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
25
|
+
if (key.toLowerCase() !== 'host' &&
|
|
26
|
+
key.toLowerCase() !== 'content-length' &&
|
|
27
|
+
value) {
|
|
28
|
+
headers[key] = Array.isArray(value) ? value[0] : value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
let response = await fetch(targetUrl, {
|
|
32
|
+
method: req.method || 'POST',
|
|
33
|
+
headers,
|
|
34
|
+
body: body || undefined,
|
|
35
|
+
});
|
|
36
|
+
if (response.status === 402) {
|
|
37
|
+
response = await handlePayment(response, targetUrl, req.method || 'POST', headers, body, privateKey, fromAddress);
|
|
38
|
+
}
|
|
39
|
+
const responseHeaders = {};
|
|
40
|
+
response.headers.forEach((v, k) => {
|
|
41
|
+
responseHeaders[k] = v;
|
|
42
|
+
});
|
|
43
|
+
res.writeHead(response.status, responseHeaders);
|
|
44
|
+
if (response.body) {
|
|
45
|
+
const reader = response.body.getReader();
|
|
46
|
+
const pump = async () => {
|
|
47
|
+
while (true) {
|
|
48
|
+
const { done, value } = await reader.read();
|
|
49
|
+
if (done) {
|
|
50
|
+
res.end();
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
res.write(value);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
pump().catch(() => res.end());
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
res.end(await response.text());
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
const msg = error instanceof Error ? error.message : 'Proxy error';
|
|
64
|
+
res.writeHead(502, { 'Content-Type': 'application/json' });
|
|
65
|
+
res.end(JSON.stringify({
|
|
66
|
+
type: 'error',
|
|
67
|
+
error: { type: 'api_error', message: msg },
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
return server;
|
|
73
|
+
}
|
|
74
|
+
async function handlePayment(response, url, method, headers, body, privateKey, fromAddress) {
|
|
75
|
+
let paymentHeader = response.headers.get('payment-required');
|
|
76
|
+
if (!paymentHeader) {
|
|
77
|
+
try {
|
|
78
|
+
const respBody = (await response.json());
|
|
79
|
+
if (respBody.x402 || respBody.accepts) {
|
|
80
|
+
paymentHeader = btoa(JSON.stringify(respBody));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// ignore parse errors
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!paymentHeader) {
|
|
88
|
+
throw new Error('402 response but no payment requirements found');
|
|
89
|
+
}
|
|
90
|
+
const paymentRequired = parsePaymentRequired(paymentHeader);
|
|
91
|
+
const details = extractPaymentDetails(paymentRequired);
|
|
92
|
+
const paymentPayload = await createPaymentPayload(privateKey, fromAddress, details.recipient, details.amount, details.network || 'eip155:8453', {
|
|
93
|
+
resourceUrl: details.resource?.url || url,
|
|
94
|
+
resourceDescription: details.resource?.description || 'BlockRun AI API call',
|
|
95
|
+
maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
|
|
96
|
+
extra: details.extra,
|
|
97
|
+
});
|
|
98
|
+
return fetch(url, {
|
|
99
|
+
method,
|
|
100
|
+
headers: {
|
|
101
|
+
...headers,
|
|
102
|
+
'PAYMENT-SIGNATURE': paymentPayload,
|
|
103
|
+
},
|
|
104
|
+
body: body || undefined,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getOrCreateWallet, scanWallets, getWalletAddress, } from '@blockrun/llm';
|
|
2
|
+
export function walletExists() {
|
|
3
|
+
const wallets = scanWallets();
|
|
4
|
+
return wallets.length > 0;
|
|
5
|
+
}
|
|
6
|
+
export function setupWallet() {
|
|
7
|
+
const { address, isNew } = getOrCreateWallet();
|
|
8
|
+
return { address, isNew };
|
|
9
|
+
}
|
|
10
|
+
export function getAddress() {
|
|
11
|
+
const addr = getWalletAddress();
|
|
12
|
+
if (!addr)
|
|
13
|
+
throw new Error('No wallet found. Run `brcc setup` first.');
|
|
14
|
+
return addr;
|
|
15
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@blockrun/cc",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Run Claude Code with any model — no rate limits, no account locks, no phone verification. Pay per use with USDC.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"brcc": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"dev": "tsc --watch",
|
|
17
|
+
"start": "node dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"claude-code",
|
|
21
|
+
"ai",
|
|
22
|
+
"llm",
|
|
23
|
+
"gpt",
|
|
24
|
+
"gemini",
|
|
25
|
+
"deepseek",
|
|
26
|
+
"anthropic",
|
|
27
|
+
"openai",
|
|
28
|
+
"x402",
|
|
29
|
+
"usdc",
|
|
30
|
+
"crypto",
|
|
31
|
+
"pay-per-use",
|
|
32
|
+
"no-rate-limit",
|
|
33
|
+
"blockrun"
|
|
34
|
+
],
|
|
35
|
+
"license": "BUSL-1.1",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/BlockRunAI/brcc"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://blockrun.ai",
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@blockrun/llm": "^1.4.2",
|
|
46
|
+
"chalk": "^5.4.0",
|
|
47
|
+
"commander": "^13.0.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^22.0.0",
|
|
51
|
+
"typescript": "^5.7.0"
|
|
52
|
+
}
|
|
53
|
+
}
|