single-file CLI (urnet.py) + README quick start + GUIDE with flags, scaling recipe, troubleshooting
This commit is contained in:
@@ -1,89 +1,142 @@
|
||||
# ur-network-farm
|
||||
# urnet — URnetwork free-tier farm
|
||||
|
||||
Free-tier **residential** egress from URnetwork (ur.io) without a card, an email, or a browser.
|
||||
Everything runs over the public API — an account, an API key and up to five hosted proxies in
|
||||
about 20 seconds.
|
||||
Turn URnetwork ([ur.io](https://ur.io)) into a rotating **residential** proxy pool. Every account
|
||||
you create gives **30 GiB of traffic per day** and **5 hosted proxies** — no card, no email, no
|
||||
captcha, no browser. Everything runs over the public API.
|
||||
|
||||
```bash
|
||||
python urnet.py farm --count 1 --proxies 3 # account + proxies, ~25 s
|
||||
python urnet.py collect --bank bank.jsonl --out pool.jsonl
|
||||
python urnet.py verify --pool pool.jsonl --limit 3
|
||||
```
|
||||
|
||||
That is the whole quick start. One account ~ 25 seconds ~ 30 GiB/day.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python **3.8+** — standard library only, nothing to `pip install`
|
||||
- `curl` — optional, but required when you route a run through a proxy (`--proxy` / `--proxy-file`).
|
||||
Windows 10/11, macOS and most Linux distros ship it. Without curl, direct (non-proxied) calls work.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
git clone https://git.reformboss.com/reform/ur-network-farm.git
|
||||
cd ur-network-farm
|
||||
python urnet.py --help
|
||||
```
|
||||
|
||||
No virtualenv, no requirements.txt, no build step, no config file.
|
||||
|
||||
## First run
|
||||
|
||||
```bash
|
||||
python urnet.py farm --count 1 # 1 account, 5 proxies in 5 countries
|
||||
|
||||
python urnet.py collect --bank bank.jsonl --out pool.jsonl
|
||||
python urnet.py export --pool pool.jsonl --format txt --out proxies.txt
|
||||
python urnet.py verify --pool pool.jsonl --limit 5
|
||||
python urnet.py balance --bank bank.jsonl
|
||||
```
|
||||
|
||||
`proxies.txt` is a plain list of ready-to-use URLs:
|
||||
|
||||
```
|
||||
https://<token>.crisp.bringyour.com:7155
|
||||
```
|
||||
|
||||
Use one directly:
|
||||
|
||||
```bash
|
||||
curl --proxy "$(head -1 proxies.txt)" https://ipinfo.io/json
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
Four API calls per account, no UI involved:
|
||||
|
||||
```
|
||||
POST /auth/network-create {"terms":true,"product_updates":false} -> network.by_jwt
|
||||
POST /auth/regenerate-seedphrase -> seedphrase (24 words)
|
||||
POST /account/api-key {"name":"farm-1"} -> urn_... key
|
||||
POST /account/api-key {"name":"urnet-1"} -> urn_... key
|
||||
POST /network/auth-client {"device_spec":"resident proxy",
|
||||
"proxy_config":{"initial_device_state":{"country_code":"us"}}}
|
||||
-> https_proxy_url (creds inside)
|
||||
GET /network/proxies -> every proxy of the account
|
||||
GET /subscription/balance -> bytes left today
|
||||
-> https_proxy_url
|
||||
```
|
||||
|
||||
Base: `https://api.bringyour.com`. Auth: `Authorization: Bearer <by_jwt | urn_key>`.
|
||||
Base: `https://api.bringyour.com`. Auth header: `Authorization: Bearer <jwt | urn_ key>`.
|
||||
`GET /network/proxies` returns every proxy of an account, `GET /subscription/balance` returns
|
||||
traffic left today.
|
||||
|
||||
## Limits (measured 2026-11-13)
|
||||
## Limits (measured, not guessed)
|
||||
|
||||
| limit | value | proof |
|
||||
|---|---|---|
|
||||
| traffic per account | **30 GiB / day**, resets 00:00 UTC | `start_balance_byte_count: 32212254720`, `start_time 2026-11-13T00:00:00Z → end_time 2026-11-14T01:00:00Z` |
|
||||
| active proxies | **5 per account** | 6th call → `{"error":{"client_limit_exceeded":true,"upgrade_required":true,"message":"Your plan's limit of 5 active proxies is reached..."}}` |
|
||||
| proxy creation rate | ~5 / minute / account | 429 on bursts; script sleeps 1.3 s |
|
||||
| instant accounts per IP | ~4, then 429 | `Too many accounts have been created recently from your network address. This limit is scoped to the address you are connecting from and is shared with everyone` |
|
||||
| countries | 20+ residential providers | 15 verified by `ipinfo` in one evening (US DE NL FR GB CA BR SE PL CH JP SG IT ES AT) |
|
||||
| limit | value |
|
||||
|---|---|
|
||||
| traffic per account | **30 GiB / day**, resets 00:00 UTC |
|
||||
| proxies per account | **5 active** — the 6th answers `client_limit_exceeded` |
|
||||
| proxy creation rate | ~5 / minute / account |
|
||||
| accounts per IP | **~4**, then `429 Too many accounts have been created recently from your network address` |
|
||||
| countries seen | 15 verified by `ipinfo`: US DE NL FR GB CA BR SE PL CH JP SG IT ES AT |
|
||||
|
||||
Bypass for the IP cap: create the first ~4 accounts directly, then feed their own proxy URLs back
|
||||
into the farm as rotating egress (`--proxy-file px.txt`). 8 more accounts went through with zero 429.
|
||||
Proof of the caps, straight from the API:
|
||||
|
||||
Pro tier ($3 first year, USDC/Zcash/Monero or card) raises it to 10 TiB/month and 1000 proxies.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# 5 accounts, 5 proxies each, direct connection
|
||||
python ur_farm.py --count 5 --proxies 5 --bank bank.jsonl
|
||||
|
||||
# more accounts, rotating egress through proxies we already own
|
||||
python ur_farm.py --count 20 --proxies 5 --proxy-file px.txt --bank bank.jsonl --start 500
|
||||
|
||||
# export every proxy URL into a flat pool
|
||||
python collect.py bank.jsonl > pool.jsonl
|
||||
|
||||
# liveness pass over the pool (ipinfo through each proxy)
|
||||
python verify.py pool.jsonl --limit 20
|
||||
```
|
||||
start_balance_byte_count: 32212254720 (30 GiB, window 2026-11-13T00:00:00Z -> 2026-11-14T01:00:00Z)
|
||||
6th proxy: {"error":{"client_limit_exceeded":true,"upgrade_required":true,
|
||||
"message":"Your plan's limit of 5 active proxies is reached..."}}
|
||||
```
|
||||
|
||||
`bank.jsonl` line shape:
|
||||
Workaround for the IP cap: create the first few accounts directly, then feed their own proxy URLs
|
||||
back into the farm as rotating egress — `--proxy-file px.txt`. Recipe:
|
||||
[GUIDE.md](GUIDE.md#scaling-past-the-ip-cap).
|
||||
|
||||
```json
|
||||
{"idx":300,"network_id":"...","name":"february-exhaust-83","jwt":"...","seed":"24 words",
|
||||
"urn":"urn_...","proxies":[{"cc":"us","url":"https://<token>@host:7155","socks":"socks5h://..."}]}
|
||||
```
|
||||
## Commands
|
||||
|
||||
| command | what it does |
|
||||
|---|---|
|
||||
| `farm` | create accounts: JWT, seed phrase, `urn_` API key, hosted proxies |
|
||||
| `collect` | flatten `bank.jsonl` into a deduplicated proxy pool |
|
||||
| `verify` | ipinfo through every proxy -> `alive / unique_ip / countries / hosting_exits` |
|
||||
| `export` | pool -> `txt` / `csv` / `env` |
|
||||
| `balance` | traffic left per account |
|
||||
|
||||
Every flag, recipe and failure mode: **[GUIDE.md](GUIDE.md)**.
|
||||
|
||||
## Proxy URL shape
|
||||
|
||||
```
|
||||
https://<40-char-token>.crisp.bringyour.com:7155 # HTTPS CONNECT, token is the credential
|
||||
socks5h://crisp.bringyour.com:7153 # SOCKS5 with username/password auth
|
||||
socks5h://crisp.bringyour.com:7153 # SOCKS5, username/password auth
|
||||
http://crisp.bringyour.com:7154 # plain HTTP
|
||||
```
|
||||
|
||||
`https_proxy_url` carries the token inline, so `curl --proxy "$url"` works as-is.
|
||||
|
||||
## Pitfalls
|
||||
## Files it writes
|
||||
|
||||
- **`country_code` is mandatory** in `initial_device_state` — omit it and the call answers `Invalid location`.
|
||||
- **Exit IP is not pinned.** The same proxy URL returned `188.103.48.237 AS3209 Vodafone Augsburg`
|
||||
and later `80.171.40.200 AS6805 Telefonica Essen`. Enable *Fixed IP* in the proxy options when a
|
||||
stable address matters, or treat stability as a known risk.
|
||||
- **Save the seed before anything else.** The account has no email and no password recovery; losing
|
||||
the JWT/seed loses the account.
|
||||
- **Do not drive the browser for this.** UI proxy creation needs clipboard reads that fail when the
|
||||
document is not focused, and copies the URL of the wrong card. `GET /network/proxies` returns every
|
||||
URL directly.
|
||||
- Proxies are residential but shared: several accounts can land on the same provider
|
||||
(two `Vodafone Hildesheim` exits were seen), so `unique_ip` is the metric, not `alive`.
|
||||
- **Not every exit is residential.** A proxy created with `country_code: br` came back as
|
||||
`209.50.178.206 AS200373 3xK Tech GmbH, Toronto` — a hosting ASN in the wrong country. The network
|
||||
is P2P, so peers supply the exit; check `ipinfo` (`org`/`country`) per proxy before trusting it for
|
||||
anything geo-sensitive, and drop rows where the ASN is a hosting provider.
|
||||
| file | content | secret? |
|
||||
|---|---|---|
|
||||
| `bank.jsonl` | one line per account: name, jwt, seed, `urn_` key, proxies | **yes** |
|
||||
| `pool.jsonl` | deduplicated proxy URLs | yes (token inside URL) |
|
||||
| `proxies.txt` / `.csv` | exports for other tools | yes |
|
||||
| `verify.json` | pool enriched with ip / country / org | no |
|
||||
|
||||
`.gitignore` excludes all of them. Keep `bank.jsonl` at `chmod 600`: the account has no email and no
|
||||
password recovery, so losing the file loses the account, and leaking it hands the account over.
|
||||
|
||||
## Troubleshooting (short version)
|
||||
|
||||
| symptom | fix |
|
||||
|---|---|
|
||||
| `429 Too many accounts ... from your network address` | add `--proxy-file px.txt` (rotate egress), or wait for the reset |
|
||||
| `Invalid location` | `country_code` missing — pass `--countries us,de` |
|
||||
| `Your plan's limit of 5 active proxies is reached` | 5 proxies per account is the free cap; `--proxies 5` max |
|
||||
| `curl returned nothing through this proxy` | proxy dead or token rotated — re-run `collect` |
|
||||
| nothing created, no error | `curl` not on PATH — install it or drop the proxy flags |
|
||||
|
||||
Full table with causes: [GUIDE.md](GUIDE.md#troubleshooting).
|
||||
|
||||
## Scope
|
||||
|
||||
Free-tier testing of a public API on accounts we create ourselves. No card data, no third-party
|
||||
accounts, no payment flows. Respect the provider's terms — this is a field note, not a licence.
|
||||
Free-tier testing of a public API on accounts you create yourself. No card data, no third-party
|
||||
accounts, no payment flows. Respect the provider's terms of service.
|
||||
|
||||
Reference in New Issue
Block a user