main
md 160 lines 5.23 KB
Rendered Raw
1 ---
2 title: SDK API
3 description: Portal SDK endpoints for relay discovery, lease lifecycle, and reverse tunnel streaming.
4 ---
5
6 # SDK API
7
8 SDK endpoints are the stable lease protocol between a Portal tunnel process and
9 a relay. Normal JSON endpoints use the shared envelope from
10 [API Reference](/api-reference). `GET /sdk/connect` is the only SDK endpoint
11 that switches to a raw stream after a successful HTTP/1.1 response.
12
13 ## Flow
14
15 1. `GET /sdk/domain` checks relay compatibility, optional ENS support, and optional relay-owned Sui x402 control-plane facilitator support.
16 2. `POST /sdk/register/challenge` creates a SIWE challenge for the requested identity.
17 3. The SDK signs the returned `siwe_message`.
18 4. `POST /sdk/register` exchanges the signature for a lease `access_token`.
19 5. The SDK keeps the lease alive with `/sdk/renew` and opens reverse streams with `/sdk/connect`.
20 6. `POST /sdk/unregister` removes the lease.
21
22 ## Endpoints
23
24 | Method | Path | Auth | Body | Data |
25 |--------|------|------|------|------|
26 | `GET` | `/sdk/domain` | None | none | `DomainResponse` |
27 | `POST` | `/sdk/register/challenge` | None | `RegisterChallengeRequest` | `RegisterChallengeResponse` |
28 | `POST` | `/sdk/register` | SIWE signature body | `RegisterRequest` | `RegisterResponse` |
29 | `POST` | `/sdk/renew` | lease token body | `RenewRequest` | `RenewResponse` |
30 | `POST` | `/sdk/unregister` | lease token body | `UnregisterRequest` | `{}` |
31 | `GET` | `/sdk/connect` | lease token header | none | hijacked stream |
32
33 ## Domain
34
35 `GET /sdk/domain` returns:
36
37 | Field | Type | Notes |
38 |-------|------|-------|
39 | `protocol_version` | `string` | SDK tunnel protocol version |
40 | `release_version` | `string` | relay software release |
41 | `ens` | `ENSStatus` | gasless ENS status |
42 | `x402` | `X402FacilitatorInfo` | relay-owned Sui x402 control-plane facilitator status |
43
44 `ENSStatus`:
45
46 | Field | Type |
47 |-------|------|
48 | `enabled`, `verified` | `boolean` |
49 | `provider`, `address`, `dnssec_state`, `ds_record`, `message`, `last_error` | `string` |
50
51 `X402FacilitatorInfo`:
52
53 | Field | Type |
54 |-------|------|
55 | `enabled` | `boolean` |
56 | `url`, `network`, `network_name`, `supported_url`, `pay_to` | `string` |
57
58 This object describes the relay's own optional x402 facilitator for
59 control-plane resources. It is separate from tunnel-owned routed HTTP payments,
60 which are configured locally by the tunnel process.
61
62 ## Register Challenge
63
64 `RegisterChallengeRequest`:
65
66 | Field | Type | Required | Notes |
67 |-------|------|----------|-------|
68 | `identity` | `Identity` | yes | `name` and `address` |
69 | `metadata` | `LeaseMetadata` | no | public lease metadata |
70 | `ttl` | `number` | no | requested TTL in seconds |
71 | `udp_enabled` | `boolean` | no | request UDP transport |
72 | `tcp_enabled` | `boolean` | no | request dedicated TCP port |
73
74 Overlay-only fields are also accepted by relay-to-relay clients:
75 `hop_token`, `route_hostname`, `hostname_hash`, and `ech_config_list`.
76
77 `RegisterChallengeResponse`:
78
79 | Field | Type |
80 |-------|------|
81 | `challenge_id` | `string` |
82 | `expires_at` | `string` |
83 | `siwe_message` | `string` |
84
85 ## Register
86
87 `RegisterRequest`:
88
89 | Field | Type | Required |
90 |-------|------|----------|
91 | `challenge_id` | `string` | yes |
92 | `siwe_message` | `string` | yes |
93 | `siwe_signature` | `string` | yes |
94 | `reported_ip` | `string` | no |
95
96 `RegisterResponse`:
97
98 | Field | Type | Notes |
99 |-------|------|-------|
100 | `identity` | `Identity` | normalized lease identity |
101 | `expires_at` | `string` | lease expiry |
102 | `access_token` | `string` | token for renew, unregister, connect, and signer access |
103 | `sni_port` | `number` | omitted when not needed |
104 | `udp_addr`, `tcp_addr` | `string` | omitted when transport is disabled |
105 | `udp_enabled`, `tcp_enabled` | `boolean` | active transport flags |
106
107 The response does not include a separate `hostname` field. The public hostname
108 is derived from the registered identity and relay root domain.
109
110 ## Renew And Unregister
111
112 `RenewRequest`:
113
114 | Field | Type | Required |
115 |-------|------|----------|
116 | `access_token` | `string` | yes |
117 | `ttl` | `number` | no |
118 | `reported_ip` | `string` | no |
119 | `metadata` | `LeaseMetadata` | no |
120
121 `RenewResponse`:
122
123 | Field | Type |
124 |-------|------|
125 | `expires_at` | `string` |
126 | `access_token` | `string` |
127
128 `UnregisterRequest`:
129
130 | Field | Type | Required |
131 |-------|------|----------|
132 | `access_token` | `string` | yes |
133
134 `/sdk/unregister` returns `{}` on success.
135
136 ## Reverse Connect
137
138 `GET /sdk/connect` opens a reverse tunnel stream.
139
140 Requirements:
141
142 | Requirement | Value |
143 |-------------|-------|
144 | HTTP version | HTTP/1.1 |
145 | Header | `X-Portal-Access-Token: <lease access_token>` |
146 | Connection | keep-alive capable connection that supports hijack |
147
148 On success, the relay writes `HTTP/1.1 200 OK` and hijacks the TCP connection.
149 There is no JSON response body. Before the hijack, failures still use the
150 standard JSON error envelope.
151
152 The SDK keeps several ready reverse streams open. When an end user connects to
153 the lease hostname, the relay claims one ready stream and bridges encrypted
154 tenant bytes between the browser side and the SDK side.
155
156 ## Relay Overlay
157
158 `/sdk/hop` is reserved for relay-to-relay overlay routing. It accepts
159 `POST` and `DELETE` with a signed `HopRoute` body and returns `HopRouteResponse`
160 or `{}`. Normal SDK clients should not call it directly.