Attach an IPRoyal ISP (static residential) proxy to a RayLink subscription in Clash Verge Rev so AI sites leave through the fixed IPRoyal IP, carried by an encrypted RayLink group. The result is verified on the running core and can be removed or rolled back.
Why a chain is required
IPRoyal ISP endpoints only accept plaintext HTTP or SOCKS5 (IPRoyal documents
TLS-to-proxy for Residential products only). Dialed directly from mainland
China, the target host is visible: blocked sites are reset, the proxy port is
then blackholed for about 90 seconds, and IPRoyal itself randomly refuses part
of the connections from a mainland source. Chained through RayLink, the same
endpoint is stable. Details and the original evidence: references/why-chain.md.
Triggers
Activate when
- "Add IPRoyal to RayLink", "configure RayLink with an IPRoyal exit", "make AI websites use IPRoyal's fixed IP"
- "IPRoyal configured on its own cannot connect / fails intermittently, but works inside RayLink"
- "Chain my IPRoyal ISP proxy behind RayLink in Clash Verge."
- "Use IPRoyal as the exit for ChatGPT/Claude on my RayLink profile."
Do not activate when
- A Clash TUN application failure unrelated to IPRoyal (WeChat images, IPv6,
DIRECT lists) — use
lov-clash-tun-doctor. - Buying proxies, choosing an airport, or bypassing an organization's network policy.
- Deploying or operating a RayLink server (adding inbounds, ports, certificates).
- Chaining IPRoyal behind a non-RayLink airport: the CLI supports any carrier
group via
--carrier, but most airports refuse to relay to IPRoyal's 1232x ports; explain that limit instead of promising it works.
User Profile (cross-session)
Read the shared user-profile/v1 scopes declared in skill.yaml on every run.
Only non-secret preferences may persist, for example a preferred carrier group or
which groups should lead with the exit, under skills.lov-iproyal-raylink.records
via scripts/profile_store.py record ... --confirm. Never persist IPRoyal
credentials in the Profile; they stay in the user's environment and in the
Clash Verge script file (mode 600). See references/user-profile.md.
Skill Group Composition
Read references/skill-composition.md. lov-clash-tun-doctor is an optional
downstream diagnostic; no sibling Skill is required.
Workflow (MANDATORY)
Resolve SKILL_DIR from the installed Skill context. All commands are
python3 "$SKILL_DIR/scripts/iproyal_raylink.py" <command>.
Step 1: Detect (read-only)
python3 "$SKILL_DIR/scripts/iproyal_raylink.py" detect
Report from the JSON: the RayLink profile found (target.uid, whether it is
current), script_state (stock / custom / managed), whether the carrier
group (TCP 稳定) and exposed groups (RayLink 代理, AI 网站代理) exist,
superseded_seq_definitions, and the controller. If no RayLink profile is
found or several are, ask the user which --profile to use.
Step 2: Collect the IPRoyal proxy without exposing it
Ask the user to put the IPRoyal dashboard string host:port:username:password
into an environment variable themselves (or a file), for example
export IPROYAL_PROXY='...' in their own terminal, or --proxy-file. Default
protocol is HTTP (port 12323); pass --type socks5 for 12324. Never echo,
log, or repeat the credentials; the CLI prints only http://***:***@host:port.
Step 3: Preview, then apply
python3 "$SKILL_DIR/scripts/iproyal_raylink.py" apply # dry run
python3 "$SKILL_DIR/scripts/iproyal_raylink.py" apply --apply --restart
stockscript: replaced by the managed block.customscript: the CLI refuses unless--wrap-existing(renames the user'smaintolovUserMainand runs it first). Tell the user before using it.managed: the block is updated in place; re-running is idempotent.--select(defaultAI 网站代理) chooses which groups lead with and are set toIPRoyal 出口; other--exposegroups only list it as an option. Use--select "RayLink 代理,AI 网站代理"only when the user wants all proxied traffic on IPRoyal.--restart(macOS) quits Clash Verge, persists the selection inprofiles.yaml, relaunches, and sets the selection through the controller. Without it, or on Windows/Linux, tell the user to restart Clash Verge and selectIPRoyal 出口inAI 网站代理.- If the target profile is not active, nothing reloads; tell the user to switch to it first.
Every write creates backups/lov-iproyal-raylink-<timestamp>/ with a manifest.
Step 4: Verify on the running core
python3 "$SKILL_DIR/scripts/iproyal_raylink.py" verify
Success requires pass: true: the exit group is loaded, the chained delay test
of IPRoyal ISP succeeds, and https://chatgpt.com/cdn-cgi/trace through the
mixed port returns the IPRoyal IP (expected_ip, default the proxy server
address; override with --expect-ip). Report the delay, selections, and trace
IP. A hint means the chain works but the AI group is not selected.
Step 5: Remove or roll back when asked
python3 "$SKILL_DIR/scripts/iproyal_raylink.py" remove --apply
python3 "$SKILL_DIR/scripts/iproyal_raylink.py" rollback --apply --restart
remove strips the managed block and restores a wrapped main byte-for-byte;
rollback restores the newest backup. Both default to dry run. Never delete
backups.
Failure handling
Read references/why-chain.md § Troubleshooting for: chain delay fails
(RayLink carrier down or blocked on the current network), trace IP is an
airport IP (AI group not selected), Clash Verge reports a script error, and
merchant Wi-Fi that blocks RayLink's non-standard ports.
Dependencies
None beyond Python 3.8+. Optional: PyYAML (more tolerant profiles.yaml
parsing), node (syntax check before writing).