@keldra/sdk 0.1.0 → 0.1.2
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/README.md +50 -1
- package/dist/{client-Bm1hg0EA.d.cts → client-COg_GErM.d.cts} +5 -0
- package/dist/{client-03PUOnb6.d.ts → client-q45X0E5a.d.ts} +5 -0
- package/dist/ethers/index.d.cts +1 -1
- package/dist/ethers/index.d.ts +1 -1
- package/dist/index.cjs +28 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +27 -0
- package/dist/viem/index.d.cts +1 -1
- package/dist/viem/index.d.ts +1 -1
- package/package.json +53 -22
package/README.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript SDK for the Keldra relay API.
|
|
4
4
|
|
|
5
|
+
## Security
|
|
6
|
+
|
|
7
|
+
- Use this SDK with a server-side API key only.
|
|
8
|
+
- Never ship `kk_...` keys in browser/client bundles.
|
|
9
|
+
- Keep `KELDRA_API_KEY` in backend environment variables.
|
|
10
|
+
|
|
5
11
|
## Install
|
|
6
12
|
|
|
7
13
|
```bash
|
|
@@ -26,7 +32,7 @@ npm install @keldra/sdk viem
|
|
|
26
32
|
```ts
|
|
27
33
|
import { KeldraClient } from "@keldra/sdk";
|
|
28
34
|
|
|
29
|
-
const client = KeldraClient.
|
|
35
|
+
const client = KeldraClient.fromEnv();
|
|
30
36
|
const result = await client.relay("ethereum", signedTxHex);
|
|
31
37
|
const limits = await client.limits();
|
|
32
38
|
const usage = await client.usage("2026-02-01", "2026-02-20");
|
|
@@ -35,6 +41,49 @@ console.log(result.relayId, result.status, result.txHash);
|
|
|
35
41
|
console.log(limits.tier, usage.totals.relays_submitted);
|
|
36
42
|
```
|
|
37
43
|
|
|
44
|
+
## API Key From .env
|
|
45
|
+
|
|
46
|
+
Use environment variables on your backend:
|
|
47
|
+
|
|
48
|
+
```env
|
|
49
|
+
KELDRA_API_KEY=kk_your_api_key
|
|
50
|
+
KELDRA_GATEWAY_URL=https://relay.keldra.io
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Then initialize directly:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { KeldraClient } from "@keldra/sdk";
|
|
57
|
+
|
|
58
|
+
const client = KeldraClient.fromEnv();
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Backend Proxy Example (Next.js)
|
|
62
|
+
|
|
63
|
+
Keep Keldra calls on your server route:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
// app/api/relay/route.ts
|
|
67
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
68
|
+
import { KeldraClient } from "@keldra/sdk";
|
|
69
|
+
|
|
70
|
+
const client = KeldraClient.fromEnv();
|
|
71
|
+
|
|
72
|
+
export async function POST(req: NextRequest) {
|
|
73
|
+
const body = await req.json();
|
|
74
|
+
const { chain, signedTx } = body as { chain: "ethereum"; signedTx: string };
|
|
75
|
+
|
|
76
|
+
if (!chain || !signedTx) {
|
|
77
|
+
return NextResponse.json({ error: "chain and signedTx are required" }, { status: 400 });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const relay = await client.relay(chain, signedTx);
|
|
81
|
+
return NextResponse.json(relay);
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Frontend calls your backend endpoint, not Keldra directly.
|
|
86
|
+
|
|
38
87
|
## Encrypted Transport
|
|
39
88
|
|
|
40
89
|
```ts
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { K as KeldraClientConfig, D as DelayProfile, E as EncryptFn, C as Chain, h as RelayResult, g as RelayResponse, i as RelayStatusResponse, H as HealthResponse, b as ChainsResponse, M as MeLimitsResponse, d as MeUsageResponse } from './types-CL-VpP9K.cjs';
|
|
2
2
|
|
|
3
|
+
type EnvMap = Record<string, string | undefined>;
|
|
3
4
|
declare class KeldraClient {
|
|
4
5
|
private readonly http;
|
|
5
6
|
private readonly gatewayUrl;
|
|
@@ -11,6 +12,10 @@ declare class KeldraClient {
|
|
|
11
12
|
private readonly encryptFn?;
|
|
12
13
|
constructor(config: KeldraClientConfig);
|
|
13
14
|
static create(apiKey: string): KeldraClient;
|
|
15
|
+
static fromEnv(env?: EnvMap, options?: {
|
|
16
|
+
apiKeyEnv?: string;
|
|
17
|
+
gatewayUrlEnv?: string;
|
|
18
|
+
}): KeldraClient;
|
|
14
19
|
static builder(): KeldraClientBuilder;
|
|
15
20
|
relay(chain: Chain, signedTx: string): Promise<RelayResult>;
|
|
16
21
|
submit(chain: Chain, signedTx: string): Promise<RelayResponse>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { K as KeldraClientConfig, D as DelayProfile, E as EncryptFn, C as Chain, h as RelayResult, g as RelayResponse, i as RelayStatusResponse, H as HealthResponse, b as ChainsResponse, M as MeLimitsResponse, d as MeUsageResponse } from './types-CL-VpP9K.js';
|
|
2
2
|
|
|
3
|
+
type EnvMap = Record<string, string | undefined>;
|
|
3
4
|
declare class KeldraClient {
|
|
4
5
|
private readonly http;
|
|
5
6
|
private readonly gatewayUrl;
|
|
@@ -11,6 +12,10 @@ declare class KeldraClient {
|
|
|
11
12
|
private readonly encryptFn?;
|
|
12
13
|
constructor(config: KeldraClientConfig);
|
|
13
14
|
static create(apiKey: string): KeldraClient;
|
|
15
|
+
static fromEnv(env?: EnvMap, options?: {
|
|
16
|
+
apiKeyEnv?: string;
|
|
17
|
+
gatewayUrlEnv?: string;
|
|
18
|
+
}): KeldraClient;
|
|
14
19
|
static builder(): KeldraClientBuilder;
|
|
15
20
|
relay(chain: Chain, signedTx: string): Promise<RelayResult>;
|
|
16
21
|
submit(chain: Chain, signedTx: string): Promise<RelayResponse>;
|
package/dist/ethers/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Signer } from 'ethers';
|
|
2
|
-
import { K as KeldraClient } from '../client-
|
|
2
|
+
import { K as KeldraClient } from '../client-COg_GErM.cjs';
|
|
3
3
|
import { C as Chain, g as RelayResponse } from '../types-CL-VpP9K.cjs';
|
|
4
4
|
|
|
5
5
|
interface KeldraBroadcasterOptions {
|
package/dist/ethers/index.d.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -164,6 +164,11 @@ var DEFAULT_GATEWAY_URL = "http://localhost:3400";
|
|
|
164
164
|
var DEFAULT_TIMEOUT_MS = 3e5;
|
|
165
165
|
var DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
166
166
|
var MAX_POLL_INTERVAL_MS = 15e3;
|
|
167
|
+
var DEFAULT_API_KEY_ENV = "KELDRA_API_KEY";
|
|
168
|
+
var DEFAULT_GATEWAY_ENV = "KELDRA_GATEWAY_URL";
|
|
169
|
+
function isBrowserRuntime() {
|
|
170
|
+
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
171
|
+
}
|
|
167
172
|
var KeldraClient = class _KeldraClient {
|
|
168
173
|
|
|
169
174
|
|
|
@@ -177,6 +182,11 @@ var KeldraClient = class _KeldraClient {
|
|
|
177
182
|
if (!config.apiKey) {
|
|
178
183
|
throw KeldraError.config("apiKey is required");
|
|
179
184
|
}
|
|
185
|
+
if (isBrowserRuntime() && config.apiKey.startsWith("kk_")) {
|
|
186
|
+
throw KeldraError.config(
|
|
187
|
+
"Do not use a Keldra API key in browser code. Move SDK calls to your backend."
|
|
188
|
+
);
|
|
189
|
+
}
|
|
180
190
|
this.http = new HttpClient(config.apiKey);
|
|
181
191
|
this.gatewayUrl = (_nullishCoalesce(config.gatewayUrl, () => ( DEFAULT_GATEWAY_URL))).replace(
|
|
182
192
|
/\/$/,
|
|
@@ -192,6 +202,23 @@ var KeldraClient = class _KeldraClient {
|
|
|
192
202
|
static create(apiKey) {
|
|
193
203
|
return new _KeldraClient({ apiKey });
|
|
194
204
|
}
|
|
205
|
+
static fromEnv(env = _nullishCoalesce(_optionalChain([globalThis, 'access', _2 => _2.process, 'optionalAccess', _3 => _3.env]), () => ( {})), options) {
|
|
206
|
+
if (isBrowserRuntime()) {
|
|
207
|
+
throw KeldraError.config(
|
|
208
|
+
"KeldraClient.fromEnv() is server-only. Load KELDRA_API_KEY on your backend."
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
const apiKeyName = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _4 => _4.apiKeyEnv]), () => ( DEFAULT_API_KEY_ENV));
|
|
212
|
+
const gatewayUrlName = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _5 => _5.gatewayUrlEnv]), () => ( DEFAULT_GATEWAY_ENV));
|
|
213
|
+
const apiKey = env[apiKeyName];
|
|
214
|
+
if (!apiKey) {
|
|
215
|
+
throw KeldraError.config(`${apiKeyName} is required`);
|
|
216
|
+
}
|
|
217
|
+
return new _KeldraClient({
|
|
218
|
+
apiKey,
|
|
219
|
+
gatewayUrl: _nullishCoalesce(env[gatewayUrlName], () => ( DEFAULT_GATEWAY_URL))
|
|
220
|
+
});
|
|
221
|
+
}
|
|
195
222
|
static builder() {
|
|
196
223
|
return new KeldraClientBuilder();
|
|
197
224
|
}
|
|
@@ -253,7 +280,7 @@ var KeldraClient = class _KeldraClient {
|
|
|
253
280
|
}
|
|
254
281
|
interval = Math.min(interval * 2, MAX_POLL_INTERVAL_MS);
|
|
255
282
|
}
|
|
256
|
-
throw KeldraError.timeout(relayId, _nullishCoalesce(_optionalChain([lastStatus, 'optionalAccess',
|
|
283
|
+
throw KeldraError.timeout(relayId, _nullishCoalesce(_optionalChain([lastStatus, 'optionalAccess', _6 => _6.status]), () => ( "queued")));
|
|
257
284
|
}
|
|
258
285
|
async health() {
|
|
259
286
|
return this.http.get(`${this.gatewayUrl}/v1/health`);
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { K as KeldraClient, a as KeldraClientBuilder } from './client-
|
|
1
|
+
export { K as KeldraClient, a as KeldraClientBuilder } from './client-COg_GErM.cjs';
|
|
2
2
|
import { R as RelayStatus } from './types-CL-VpP9K.cjs';
|
|
3
3
|
export { C as Chain, a as ChainConfig, b as ChainsResponse, D as DelayProfile, E as EncryptFn, H as HealthResponse, c as HealthStats, K as KeldraClientConfig, M as MeLimitsResponse, d as MeUsageResponse, N as NoiseKeyResponse, e as RelayOptions, f as RelayRequest, g as RelayResponse, h as RelayResult, i as RelayStatusResponse, T as TERMINAL_STATUSES, U as UsageDailyRow, j as UsageTotals } from './types-CL-VpP9K.cjs';
|
|
4
4
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { K as KeldraClient, a as KeldraClientBuilder } from './client-
|
|
1
|
+
export { K as KeldraClient, a as KeldraClientBuilder } from './client-q45X0E5a.js';
|
|
2
2
|
import { R as RelayStatus } from './types-CL-VpP9K.js';
|
|
3
3
|
export { C as Chain, a as ChainConfig, b as ChainsResponse, D as DelayProfile, E as EncryptFn, H as HealthResponse, c as HealthStats, K as KeldraClientConfig, M as MeLimitsResponse, d as MeUsageResponse, N as NoiseKeyResponse, e as RelayOptions, f as RelayRequest, g as RelayResponse, h as RelayResult, i as RelayStatusResponse, T as TERMINAL_STATUSES, U as UsageDailyRow, j as UsageTotals } from './types-CL-VpP9K.js';
|
|
4
4
|
|
package/dist/index.js
CHANGED
|
@@ -164,6 +164,11 @@ var DEFAULT_GATEWAY_URL = "http://localhost:3400";
|
|
|
164
164
|
var DEFAULT_TIMEOUT_MS = 3e5;
|
|
165
165
|
var DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
166
166
|
var MAX_POLL_INTERVAL_MS = 15e3;
|
|
167
|
+
var DEFAULT_API_KEY_ENV = "KELDRA_API_KEY";
|
|
168
|
+
var DEFAULT_GATEWAY_ENV = "KELDRA_GATEWAY_URL";
|
|
169
|
+
function isBrowserRuntime() {
|
|
170
|
+
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
171
|
+
}
|
|
167
172
|
var KeldraClient = class _KeldraClient {
|
|
168
173
|
http;
|
|
169
174
|
gatewayUrl;
|
|
@@ -177,6 +182,11 @@ var KeldraClient = class _KeldraClient {
|
|
|
177
182
|
if (!config.apiKey) {
|
|
178
183
|
throw KeldraError.config("apiKey is required");
|
|
179
184
|
}
|
|
185
|
+
if (isBrowserRuntime() && config.apiKey.startsWith("kk_")) {
|
|
186
|
+
throw KeldraError.config(
|
|
187
|
+
"Do not use a Keldra API key in browser code. Move SDK calls to your backend."
|
|
188
|
+
);
|
|
189
|
+
}
|
|
180
190
|
this.http = new HttpClient(config.apiKey);
|
|
181
191
|
this.gatewayUrl = (config.gatewayUrl ?? DEFAULT_GATEWAY_URL).replace(
|
|
182
192
|
/\/$/,
|
|
@@ -192,6 +202,23 @@ var KeldraClient = class _KeldraClient {
|
|
|
192
202
|
static create(apiKey) {
|
|
193
203
|
return new _KeldraClient({ apiKey });
|
|
194
204
|
}
|
|
205
|
+
static fromEnv(env = globalThis.process?.env ?? {}, options) {
|
|
206
|
+
if (isBrowserRuntime()) {
|
|
207
|
+
throw KeldraError.config(
|
|
208
|
+
"KeldraClient.fromEnv() is server-only. Load KELDRA_API_KEY on your backend."
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
const apiKeyName = options?.apiKeyEnv ?? DEFAULT_API_KEY_ENV;
|
|
212
|
+
const gatewayUrlName = options?.gatewayUrlEnv ?? DEFAULT_GATEWAY_ENV;
|
|
213
|
+
const apiKey = env[apiKeyName];
|
|
214
|
+
if (!apiKey) {
|
|
215
|
+
throw KeldraError.config(`${apiKeyName} is required`);
|
|
216
|
+
}
|
|
217
|
+
return new _KeldraClient({
|
|
218
|
+
apiKey,
|
|
219
|
+
gatewayUrl: env[gatewayUrlName] ?? DEFAULT_GATEWAY_URL
|
|
220
|
+
});
|
|
221
|
+
}
|
|
195
222
|
static builder() {
|
|
196
223
|
return new KeldraClientBuilder();
|
|
197
224
|
}
|
package/dist/viem/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Transport, Chain as Chain$1, Account, WalletClient } from 'viem';
|
|
2
|
-
import { K as KeldraClient } from '../client-
|
|
2
|
+
import { K as KeldraClient } from '../client-COg_GErM.cjs';
|
|
3
3
|
import { C as Chain } from '../types-CL-VpP9K.cjs';
|
|
4
4
|
|
|
5
5
|
interface KeldraViemOptions {
|
package/dist/viem/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Transport, Chain as Chain$1, Account, WalletClient } from 'viem';
|
|
2
|
-
import { K as KeldraClient } from '../client-
|
|
2
|
+
import { K as KeldraClient } from '../client-q45X0E5a.js';
|
|
3
3
|
import { C as Chain } from '../types-CL-VpP9K.js';
|
|
4
4
|
|
|
5
5
|
interface KeldraViemOptions {
|
package/package.json
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keldra/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "TypeScript SDK for Keldra relay API",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Keldra",
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/jperth86/keldra_relay.git"
|
|
10
|
-
},
|
|
11
7
|
"homepage": "https://keldra.network",
|
|
12
|
-
"bugs": {
|
|
13
|
-
"url": "https://github.com/jperth86/keldra_relay/issues"
|
|
14
|
-
},
|
|
15
8
|
"keywords": [
|
|
16
9
|
"keldra",
|
|
17
10
|
"relay",
|
|
@@ -33,23 +26,51 @@
|
|
|
33
26
|
},
|
|
34
27
|
"exports": {
|
|
35
28
|
".": {
|
|
36
|
-
"import": {
|
|
37
|
-
|
|
29
|
+
"import": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"default": "./dist/index.js"
|
|
32
|
+
},
|
|
33
|
+
"require": {
|
|
34
|
+
"types": "./dist/index.d.cts",
|
|
35
|
+
"default": "./dist/index.cjs"
|
|
36
|
+
}
|
|
38
37
|
},
|
|
39
38
|
"./crypto": {
|
|
40
|
-
"import": {
|
|
41
|
-
|
|
39
|
+
"import": {
|
|
40
|
+
"types": "./dist/crypto/index.d.ts",
|
|
41
|
+
"default": "./dist/crypto/index.js"
|
|
42
|
+
},
|
|
43
|
+
"require": {
|
|
44
|
+
"types": "./dist/crypto/index.d.cts",
|
|
45
|
+
"default": "./dist/crypto/index.cjs"
|
|
46
|
+
}
|
|
42
47
|
},
|
|
43
48
|
"./ethers": {
|
|
44
|
-
"import": {
|
|
45
|
-
|
|
49
|
+
"import": {
|
|
50
|
+
"types": "./dist/ethers/index.d.ts",
|
|
51
|
+
"default": "./dist/ethers/index.js"
|
|
52
|
+
},
|
|
53
|
+
"require": {
|
|
54
|
+
"types": "./dist/ethers/index.d.cts",
|
|
55
|
+
"default": "./dist/ethers/index.cjs"
|
|
56
|
+
}
|
|
46
57
|
},
|
|
47
58
|
"./viem": {
|
|
48
|
-
"import": {
|
|
49
|
-
|
|
59
|
+
"import": {
|
|
60
|
+
"types": "./dist/viem/index.d.ts",
|
|
61
|
+
"default": "./dist/viem/index.js"
|
|
62
|
+
},
|
|
63
|
+
"require": {
|
|
64
|
+
"types": "./dist/viem/index.d.cts",
|
|
65
|
+
"default": "./dist/viem/index.cjs"
|
|
66
|
+
}
|
|
50
67
|
}
|
|
51
68
|
},
|
|
52
|
-
"files": [
|
|
69
|
+
"files": [
|
|
70
|
+
"dist",
|
|
71
|
+
"README.md",
|
|
72
|
+
"LICENSE"
|
|
73
|
+
],
|
|
53
74
|
"scripts": {
|
|
54
75
|
"build": "tsup",
|
|
55
76
|
"test": "vitest run",
|
|
@@ -65,11 +86,21 @@
|
|
|
65
86
|
"viem": "^2.0.0"
|
|
66
87
|
},
|
|
67
88
|
"peerDependenciesMeta": {
|
|
68
|
-
"@stablelib/blake2s": {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
|
|
89
|
+
"@stablelib/blake2s": {
|
|
90
|
+
"optional": true
|
|
91
|
+
},
|
|
92
|
+
"@stablelib/chacha20poly1305": {
|
|
93
|
+
"optional": true
|
|
94
|
+
},
|
|
95
|
+
"@stablelib/x25519": {
|
|
96
|
+
"optional": true
|
|
97
|
+
},
|
|
98
|
+
"ethers": {
|
|
99
|
+
"optional": true
|
|
100
|
+
},
|
|
101
|
+
"viem": {
|
|
102
|
+
"optional": true
|
|
103
|
+
}
|
|
73
104
|
},
|
|
74
105
|
"devDependencies": {
|
|
75
106
|
"@stablelib/blake2s": "^2.0.0",
|