@keldra/sdk 0.1.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/dist/index.js ADDED
@@ -0,0 +1,331 @@
1
+ // src/errors.ts
2
+ var KeldraError = class _KeldraError extends Error {
3
+ code;
4
+ cause;
5
+ constructor(code, message, cause) {
6
+ super(message);
7
+ this.name = "KeldraError";
8
+ this.code = code;
9
+ this.cause = cause;
10
+ }
11
+ static http(message, cause) {
12
+ return new _KeldraError("HTTP", `HTTP request failed: ${message}`, cause);
13
+ }
14
+ static api(status, message) {
15
+ return new KeldraApiError(status, message);
16
+ }
17
+ static timeout(relayId, lastStatus) {
18
+ return new KeldraTimeoutError(relayId, lastStatus);
19
+ }
20
+ static invalidTransaction(message) {
21
+ return new _KeldraError(
22
+ "INVALID_TRANSACTION",
23
+ `Invalid transaction: ${message}`
24
+ );
25
+ }
26
+ static config(message) {
27
+ return new _KeldraError("CONFIG", `SDK configuration error: ${message}`);
28
+ }
29
+ };
30
+ var KeldraApiError = class extends KeldraError {
31
+ status;
32
+ constructor(status, message) {
33
+ super("API", `API error (HTTP ${status}): ${message}`);
34
+ this.name = "KeldraApiError";
35
+ this.status = status;
36
+ }
37
+ };
38
+ var KeldraTimeoutError = class extends KeldraError {
39
+ relayId;
40
+ lastStatus;
41
+ constructor(relayId, lastStatus) {
42
+ super(
43
+ "TIMEOUT",
44
+ `Relay ${relayId} timed out (last status: ${lastStatus})`
45
+ );
46
+ this.name = "KeldraTimeoutError";
47
+ this.relayId = relayId;
48
+ this.lastStatus = lastStatus;
49
+ }
50
+ };
51
+
52
+ // src/utils.ts
53
+ function parseHex(hexStr) {
54
+ const cleaned = hexStr.startsWith("0x") ? hexStr.slice(2) : hexStr;
55
+ if (cleaned.length === 0) {
56
+ throw KeldraError.invalidTransaction("empty transaction");
57
+ }
58
+ if (cleaned.length % 2 !== 0 || !/^[0-9a-fA-F]+$/.test(cleaned)) {
59
+ throw KeldraError.invalidTransaction(`invalid hex: ${hexStr}`);
60
+ }
61
+ const bytes = new Uint8Array(cleaned.length / 2);
62
+ for (let i = 0; i < cleaned.length; i += 2) {
63
+ bytes[i / 2] = parseInt(cleaned.substring(i, i + 2), 16);
64
+ }
65
+ return bytes;
66
+ }
67
+ function toHex(bytes) {
68
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
69
+ }
70
+ function toBase64(bytes) {
71
+ if (typeof Buffer !== "undefined") {
72
+ return Buffer.from(bytes).toString("base64");
73
+ }
74
+ let binary = "";
75
+ for (let i = 0; i < bytes.length; i++) {
76
+ binary += String.fromCharCode(bytes[i]);
77
+ }
78
+ return btoa(binary);
79
+ }
80
+ function extractErrorMessage(body) {
81
+ try {
82
+ const parsed = JSON.parse(body);
83
+ if (typeof parsed?.error === "string") return parsed.error;
84
+ } catch {
85
+ }
86
+ return body;
87
+ }
88
+ function sleep(ms) {
89
+ return new Promise((resolve) => setTimeout(resolve, ms));
90
+ }
91
+
92
+ // src/http.ts
93
+ var HttpClient = class {
94
+ baseHeaders;
95
+ constructor(bearerToken) {
96
+ this.baseHeaders = { "Content-Type": "application/json" };
97
+ if (bearerToken) {
98
+ this.baseHeaders["Authorization"] = `Bearer ${bearerToken}`;
99
+ }
100
+ }
101
+ async get(url) {
102
+ return this.request("GET", url);
103
+ }
104
+ async post(url, body) {
105
+ return this.request("POST", url, body);
106
+ }
107
+ async request(method, url, body) {
108
+ let response;
109
+ try {
110
+ response = await fetch(url, {
111
+ method,
112
+ headers: this.baseHeaders,
113
+ body: body ? JSON.stringify(body) : void 0
114
+ });
115
+ } catch (err) {
116
+ throw KeldraError.http(String(err), err);
117
+ }
118
+ if (!response.ok) {
119
+ const text = await response.text().catch(() => "");
120
+ throw KeldraError.api(response.status, extractErrorMessage(text));
121
+ }
122
+ return response.json();
123
+ }
124
+ };
125
+
126
+ // src/padding.ts
127
+ var BUCKETS = [512, 1024, 2048, 4096];
128
+ function padTransaction(rawTx) {
129
+ const originalLen = rawTx.length;
130
+ const totalNeeded = originalLen + 4;
131
+ const bucket = BUCKETS.find((b) => b >= totalNeeded);
132
+ if (!bucket) {
133
+ throw new Error(
134
+ `Transaction too large: ${originalLen} bytes (max ${BUCKETS[BUCKETS.length - 1] - 4} bytes)`
135
+ );
136
+ }
137
+ const padded = new Uint8Array(bucket);
138
+ padded.set(rawTx, 0);
139
+ const paddingLen = bucket - totalNeeded;
140
+ if (paddingLen > 0) {
141
+ const randomBytes = crypto.getRandomValues(new Uint8Array(paddingLen));
142
+ padded.set(randomBytes, originalLen);
143
+ }
144
+ const view = new DataView(padded.buffer, padded.byteOffset);
145
+ view.setUint32(bucket - 4, originalLen, false);
146
+ return padded;
147
+ }
148
+ function unpadTransaction(padded) {
149
+ if (padded.length < 4) return null;
150
+ const view = new DataView(padded.buffer, padded.byteOffset);
151
+ const originalLen = view.getUint32(padded.length - 4, false);
152
+ if (originalLen > padded.length - 4) return null;
153
+ return padded.slice(0, originalLen);
154
+ }
155
+
156
+ // src/types.ts
157
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
158
+ "confirmed",
159
+ "failed"
160
+ ]);
161
+
162
+ // src/client.ts
163
+ var DEFAULT_GATEWAY_URL = "http://localhost:3400";
164
+ var DEFAULT_TIMEOUT_MS = 3e5;
165
+ var DEFAULT_POLL_INTERVAL_MS = 2e3;
166
+ var MAX_POLL_INTERVAL_MS = 15e3;
167
+ var KeldraClient = class _KeldraClient {
168
+ http;
169
+ gatewayUrl;
170
+ defaultDelayProfile;
171
+ confirmationTimeoutMs;
172
+ pollIntervalMs;
173
+ noisePublicKey;
174
+ noiseKid;
175
+ encryptFn;
176
+ constructor(config) {
177
+ if (!config.apiKey) {
178
+ throw KeldraError.config("apiKey is required");
179
+ }
180
+ this.http = new HttpClient(config.apiKey);
181
+ this.gatewayUrl = (config.gatewayUrl ?? DEFAULT_GATEWAY_URL).replace(
182
+ /\/$/,
183
+ ""
184
+ );
185
+ this.defaultDelayProfile = config.delayProfile ?? "balanced";
186
+ this.confirmationTimeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
187
+ this.pollIntervalMs = config.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
188
+ this.noisePublicKey = config.noisePublicKey;
189
+ this.noiseKid = config.noiseKid;
190
+ this.encryptFn = config.encryptFn;
191
+ }
192
+ static create(apiKey) {
193
+ return new _KeldraClient({ apiKey });
194
+ }
195
+ static builder() {
196
+ return new KeldraClientBuilder();
197
+ }
198
+ async relay(chain, signedTx) {
199
+ const start = Date.now();
200
+ const response = await this.submit(chain, signedTx);
201
+ const result = await this.waitForConfirmation(response.relay_id);
202
+ return {
203
+ relayId: response.relay_id,
204
+ status: result.status,
205
+ txHash: result.tx_hash,
206
+ durationMs: Date.now() - start,
207
+ error: result.error
208
+ };
209
+ }
210
+ async submit(chain, signedTx) {
211
+ const rawBytes = parseHex(signedTx);
212
+ const padded = padTransaction(rawBytes);
213
+ let request;
214
+ if (this.noisePublicKey && this.noiseKid && this.encryptFn) {
215
+ const encrypted = await this.encryptFn(padded, this.noisePublicKey);
216
+ const b64 = toBase64(encrypted);
217
+ request = {
218
+ chain,
219
+ signed_tx: "",
220
+ options: { delay_profile: this.defaultDelayProfile },
221
+ encrypted_payload: b64,
222
+ noise_kid: this.noiseKid
223
+ };
224
+ } else {
225
+ request = {
226
+ chain,
227
+ signed_tx: `0x${toHex(padded)}`,
228
+ options: { delay_profile: this.defaultDelayProfile }
229
+ };
230
+ }
231
+ return this.http.post(
232
+ `${this.gatewayUrl}/v1/relay`,
233
+ request
234
+ );
235
+ }
236
+ async status(relayId) {
237
+ return this.http.get(
238
+ `${this.gatewayUrl}/v1/relay/${relayId}/status`
239
+ );
240
+ }
241
+ async waitForConfirmation(relayId) {
242
+ const deadline = Date.now() + this.confirmationTimeoutMs;
243
+ let interval = this.pollIntervalMs;
244
+ let lastStatus;
245
+ while (Date.now() < deadline) {
246
+ await sleep(interval);
247
+ try {
248
+ lastStatus = await this.status(relayId);
249
+ if (TERMINAL_STATUSES.has(lastStatus.status)) {
250
+ return lastStatus;
251
+ }
252
+ } catch {
253
+ }
254
+ interval = Math.min(interval * 2, MAX_POLL_INTERVAL_MS);
255
+ }
256
+ throw KeldraError.timeout(relayId, lastStatus?.status ?? "queued");
257
+ }
258
+ async health() {
259
+ return this.http.get(`${this.gatewayUrl}/v1/health`);
260
+ }
261
+ async chains() {
262
+ return this.http.get(`${this.gatewayUrl}/v1/chains`);
263
+ }
264
+ async limits() {
265
+ return this.http.get(`${this.gatewayUrl}/v1/me/limits`);
266
+ }
267
+ async usage(from, to) {
268
+ const params = new URLSearchParams({ from, to });
269
+ return this.http.get(
270
+ `${this.gatewayUrl}/v1/me/usage?${params.toString()}`
271
+ );
272
+ }
273
+ async fetchNoiseKey() {
274
+ const resp = await this.http.get(
275
+ `${this.gatewayUrl}/v1/noise-key`
276
+ );
277
+ this.noisePublicKey = resp.public_key;
278
+ this.noiseKid = resp.kid;
279
+ }
280
+ get encrypted() {
281
+ return !!(this.noisePublicKey && this.noiseKid && this.encryptFn);
282
+ }
283
+ };
284
+ var KeldraClientBuilder = class {
285
+ config = {};
286
+ apiKey(key) {
287
+ this.config.apiKey = key;
288
+ return this;
289
+ }
290
+ gatewayUrl(url) {
291
+ this.config.gatewayUrl = url;
292
+ return this;
293
+ }
294
+ delayProfile(profile) {
295
+ this.config.delayProfile = profile;
296
+ return this;
297
+ }
298
+ timeout(ms) {
299
+ this.config.timeoutMs = ms;
300
+ return this;
301
+ }
302
+ pollInterval(ms) {
303
+ this.config.pollIntervalMs = ms;
304
+ return this;
305
+ }
306
+ noisePublicKey(key, kid) {
307
+ this.config.noisePublicKey = key;
308
+ this.config.noiseKid = kid;
309
+ return this;
310
+ }
311
+ withEncryption(fn) {
312
+ this.config.encryptFn = fn;
313
+ return this;
314
+ }
315
+ build() {
316
+ if (!this.config.apiKey) {
317
+ throw KeldraError.config("apiKey is required");
318
+ }
319
+ return new KeldraClient(this.config);
320
+ }
321
+ };
322
+ export {
323
+ KeldraApiError,
324
+ KeldraClient,
325
+ KeldraClientBuilder,
326
+ KeldraError,
327
+ KeldraTimeoutError,
328
+ TERMINAL_STATUSES,
329
+ padTransaction,
330
+ unpadTransaction
331
+ };
@@ -0,0 +1,121 @@
1
+ type Chain = 'ethereum' | 'arbitrum' | 'optimism' | 'base' | 'polygon';
2
+ type DelayProfile = 'fast' | 'balanced' | 'maximum_privacy';
3
+ type RelayStatus = 'queued' | 'batched' | 'injected' | 'confirmed' | 'failed';
4
+ declare const TERMINAL_STATUSES: ReadonlySet<RelayStatus>;
5
+ interface RelayRequest {
6
+ chain: Chain;
7
+ signed_tx: string;
8
+ options: RelayOptions;
9
+ encrypted_payload?: string;
10
+ noise_kid?: string;
11
+ }
12
+ interface RelayOptions {
13
+ delay_profile: DelayProfile;
14
+ }
15
+ interface RelayResponse {
16
+ relay_id: string;
17
+ estimated_broadcast_min_secs: number;
18
+ estimated_broadcast_max_secs: number;
19
+ }
20
+ interface RelayStatusResponse {
21
+ relay_id: string;
22
+ status: RelayStatus;
23
+ queued_at: string;
24
+ batched_at?: string;
25
+ injected_at?: string;
26
+ confirmed_at?: string;
27
+ tx_hash?: string;
28
+ error?: string;
29
+ }
30
+ interface RelayResult {
31
+ relayId: string;
32
+ status: RelayStatus;
33
+ txHash?: string;
34
+ durationMs: number;
35
+ error?: string;
36
+ }
37
+ interface HealthResponse {
38
+ status: string;
39
+ gateway_regions: string[];
40
+ injection_regions: string[];
41
+ supported_chains: string[];
42
+ stats: HealthStats;
43
+ }
44
+ interface HealthStats {
45
+ active_relays: number;
46
+ total_relays: number;
47
+ queued: number;
48
+ batched: number;
49
+ injected: number;
50
+ confirmed: number;
51
+ failed: number;
52
+ }
53
+ interface ChainsResponse {
54
+ chains: ChainConfig[];
55
+ }
56
+ interface ChainConfig {
57
+ chain: Chain;
58
+ name: string;
59
+ min_batch_size: number;
60
+ epoch_duration_secs: number;
61
+ injection_node_count: number;
62
+ confirmation_timeout_secs: number;
63
+ enabled: boolean;
64
+ }
65
+ interface NoiseKeyResponse {
66
+ kid: string;
67
+ public_key: string;
68
+ protocol: string;
69
+ }
70
+ interface MeLimitsResponse {
71
+ api_key: string;
72
+ key_id: string;
73
+ tier: string;
74
+ limits: EffectiveLimits;
75
+ usage: CurrentUsage;
76
+ }
77
+ interface EffectiveLimits {
78
+ requests_per_minute: number;
79
+ max_inflight: number;
80
+ monthly_quota_relays: number;
81
+ min_poll_interval_ms: number;
82
+ max_body_bytes: number;
83
+ }
84
+ interface CurrentUsage {
85
+ month: string;
86
+ monthly_relays_submitted: number;
87
+ monthly_remaining_relays: number;
88
+ inflight_relays: number;
89
+ }
90
+ interface MeUsageResponse {
91
+ daily: UsageDailyRow[];
92
+ totals: UsageTotals;
93
+ }
94
+ interface UsageDailyRow {
95
+ day: string;
96
+ api_key: string;
97
+ tier: string;
98
+ relays_submitted: number;
99
+ relays_confirmed: number;
100
+ relays_failed: number;
101
+ bytes_ingested: number;
102
+ }
103
+ interface UsageTotals {
104
+ relays_submitted: number;
105
+ relays_confirmed: number;
106
+ relays_failed: number;
107
+ bytes_ingested: number;
108
+ }
109
+ type EncryptFn = (plaintext: Uint8Array, gatewayPublicKeyHex: string) => Promise<Uint8Array>;
110
+ interface KeldraClientConfig {
111
+ apiKey: string;
112
+ gatewayUrl?: string;
113
+ delayProfile?: DelayProfile;
114
+ timeoutMs?: number;
115
+ pollIntervalMs?: number;
116
+ noisePublicKey?: string;
117
+ noiseKid?: string;
118
+ encryptFn?: EncryptFn;
119
+ }
120
+
121
+ export { type Chain as C, type DelayProfile as D, type EncryptFn as E, type HealthResponse as H, type KeldraClientConfig as K, type MeLimitsResponse as M, type NoiseKeyResponse as N, type RelayStatus as R, TERMINAL_STATUSES as T, type UsageDailyRow as U, type ChainConfig as a, type ChainsResponse as b, type HealthStats as c, type MeUsageResponse as d, type RelayOptions as e, type RelayRequest as f, type RelayResponse as g, type RelayResult as h, type RelayStatusResponse as i, type UsageTotals as j };
@@ -0,0 +1,121 @@
1
+ type Chain = 'ethereum' | 'arbitrum' | 'optimism' | 'base' | 'polygon';
2
+ type DelayProfile = 'fast' | 'balanced' | 'maximum_privacy';
3
+ type RelayStatus = 'queued' | 'batched' | 'injected' | 'confirmed' | 'failed';
4
+ declare const TERMINAL_STATUSES: ReadonlySet<RelayStatus>;
5
+ interface RelayRequest {
6
+ chain: Chain;
7
+ signed_tx: string;
8
+ options: RelayOptions;
9
+ encrypted_payload?: string;
10
+ noise_kid?: string;
11
+ }
12
+ interface RelayOptions {
13
+ delay_profile: DelayProfile;
14
+ }
15
+ interface RelayResponse {
16
+ relay_id: string;
17
+ estimated_broadcast_min_secs: number;
18
+ estimated_broadcast_max_secs: number;
19
+ }
20
+ interface RelayStatusResponse {
21
+ relay_id: string;
22
+ status: RelayStatus;
23
+ queued_at: string;
24
+ batched_at?: string;
25
+ injected_at?: string;
26
+ confirmed_at?: string;
27
+ tx_hash?: string;
28
+ error?: string;
29
+ }
30
+ interface RelayResult {
31
+ relayId: string;
32
+ status: RelayStatus;
33
+ txHash?: string;
34
+ durationMs: number;
35
+ error?: string;
36
+ }
37
+ interface HealthResponse {
38
+ status: string;
39
+ gateway_regions: string[];
40
+ injection_regions: string[];
41
+ supported_chains: string[];
42
+ stats: HealthStats;
43
+ }
44
+ interface HealthStats {
45
+ active_relays: number;
46
+ total_relays: number;
47
+ queued: number;
48
+ batched: number;
49
+ injected: number;
50
+ confirmed: number;
51
+ failed: number;
52
+ }
53
+ interface ChainsResponse {
54
+ chains: ChainConfig[];
55
+ }
56
+ interface ChainConfig {
57
+ chain: Chain;
58
+ name: string;
59
+ min_batch_size: number;
60
+ epoch_duration_secs: number;
61
+ injection_node_count: number;
62
+ confirmation_timeout_secs: number;
63
+ enabled: boolean;
64
+ }
65
+ interface NoiseKeyResponse {
66
+ kid: string;
67
+ public_key: string;
68
+ protocol: string;
69
+ }
70
+ interface MeLimitsResponse {
71
+ api_key: string;
72
+ key_id: string;
73
+ tier: string;
74
+ limits: EffectiveLimits;
75
+ usage: CurrentUsage;
76
+ }
77
+ interface EffectiveLimits {
78
+ requests_per_minute: number;
79
+ max_inflight: number;
80
+ monthly_quota_relays: number;
81
+ min_poll_interval_ms: number;
82
+ max_body_bytes: number;
83
+ }
84
+ interface CurrentUsage {
85
+ month: string;
86
+ monthly_relays_submitted: number;
87
+ monthly_remaining_relays: number;
88
+ inflight_relays: number;
89
+ }
90
+ interface MeUsageResponse {
91
+ daily: UsageDailyRow[];
92
+ totals: UsageTotals;
93
+ }
94
+ interface UsageDailyRow {
95
+ day: string;
96
+ api_key: string;
97
+ tier: string;
98
+ relays_submitted: number;
99
+ relays_confirmed: number;
100
+ relays_failed: number;
101
+ bytes_ingested: number;
102
+ }
103
+ interface UsageTotals {
104
+ relays_submitted: number;
105
+ relays_confirmed: number;
106
+ relays_failed: number;
107
+ bytes_ingested: number;
108
+ }
109
+ type EncryptFn = (plaintext: Uint8Array, gatewayPublicKeyHex: string) => Promise<Uint8Array>;
110
+ interface KeldraClientConfig {
111
+ apiKey: string;
112
+ gatewayUrl?: string;
113
+ delayProfile?: DelayProfile;
114
+ timeoutMs?: number;
115
+ pollIntervalMs?: number;
116
+ noisePublicKey?: string;
117
+ noiseKid?: string;
118
+ encryptFn?: EncryptFn;
119
+ }
120
+
121
+ export { type Chain as C, type DelayProfile as D, type EncryptFn as E, type HealthResponse as H, type KeldraClientConfig as K, type MeLimitsResponse as M, type NoiseKeyResponse as N, type RelayStatus as R, TERMINAL_STATUSES as T, type UsageDailyRow as U, type ChainConfig as a, type ChainsResponse as b, type HealthStats as c, type MeUsageResponse as d, type RelayOptions as e, type RelayRequest as f, type RelayResponse as g, type RelayResult as h, type RelayStatusResponse as i, type UsageTotals as j };
@@ -0,0 +1,34 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/viem/index.ts
2
+ function wrapWalletClient(walletClient, options) {
3
+ return {
4
+ ...walletClient,
5
+ sendTransaction: (async (args) => {
6
+ const request = await walletClient.prepareTransactionRequest(
7
+ args
8
+ );
9
+ const signedTx = await walletClient.signTransaction(request);
10
+ const response = await options.client.submit(
11
+ options.chain,
12
+ signedTx
13
+ );
14
+ return response.relay_id;
15
+ })
16
+ };
17
+ }
18
+ function keldraTransportAction(options) {
19
+ return {
20
+ async sendRawTransaction({
21
+ serializedTransaction
22
+ }) {
23
+ const response = await options.client.submit(
24
+ options.chain,
25
+ serializedTransaction
26
+ );
27
+ return response.relay_id;
28
+ }
29
+ };
30
+ }
31
+
32
+
33
+
34
+ exports.keldraTransportAction = keldraTransportAction; exports.wrapWalletClient = wrapWalletClient;
@@ -0,0 +1,16 @@
1
+ import { Transport, Chain as Chain$1, Account, WalletClient } from 'viem';
2
+ import { K as KeldraClient } from '../client-Bm1hg0EA.cjs';
3
+ import { C as Chain } from '../types-CL-VpP9K.cjs';
4
+
5
+ interface KeldraViemOptions {
6
+ client: KeldraClient;
7
+ chain: Chain;
8
+ }
9
+ declare function wrapWalletClient<TTransport extends Transport = Transport, TChain extends Chain$1 | undefined = Chain$1 | undefined, TAccount extends Account | undefined = Account | undefined>(walletClient: WalletClient<TTransport, TChain, TAccount>, options: KeldraViemOptions): WalletClient<TTransport, TChain, TAccount>;
10
+ declare function keldraTransportAction(options: KeldraViemOptions): {
11
+ sendRawTransaction({ serializedTransaction, }: {
12
+ serializedTransaction: string;
13
+ }): Promise<string>;
14
+ };
15
+
16
+ export { type KeldraViemOptions, keldraTransportAction, wrapWalletClient };
@@ -0,0 +1,16 @@
1
+ import { Transport, Chain as Chain$1, Account, WalletClient } from 'viem';
2
+ import { K as KeldraClient } from '../client-03PUOnb6.js';
3
+ import { C as Chain } from '../types-CL-VpP9K.js';
4
+
5
+ interface KeldraViemOptions {
6
+ client: KeldraClient;
7
+ chain: Chain;
8
+ }
9
+ declare function wrapWalletClient<TTransport extends Transport = Transport, TChain extends Chain$1 | undefined = Chain$1 | undefined, TAccount extends Account | undefined = Account | undefined>(walletClient: WalletClient<TTransport, TChain, TAccount>, options: KeldraViemOptions): WalletClient<TTransport, TChain, TAccount>;
10
+ declare function keldraTransportAction(options: KeldraViemOptions): {
11
+ sendRawTransaction({ serializedTransaction, }: {
12
+ serializedTransaction: string;
13
+ }): Promise<string>;
14
+ };
15
+
16
+ export { type KeldraViemOptions, keldraTransportAction, wrapWalletClient };
@@ -0,0 +1,34 @@
1
+ // src/viem/index.ts
2
+ function wrapWalletClient(walletClient, options) {
3
+ return {
4
+ ...walletClient,
5
+ sendTransaction: (async (args) => {
6
+ const request = await walletClient.prepareTransactionRequest(
7
+ args
8
+ );
9
+ const signedTx = await walletClient.signTransaction(request);
10
+ const response = await options.client.submit(
11
+ options.chain,
12
+ signedTx
13
+ );
14
+ return response.relay_id;
15
+ })
16
+ };
17
+ }
18
+ function keldraTransportAction(options) {
19
+ return {
20
+ async sendRawTransaction({
21
+ serializedTransaction
22
+ }) {
23
+ const response = await options.client.submit(
24
+ options.chain,
25
+ serializedTransaction
26
+ );
27
+ return response.relay_id;
28
+ }
29
+ };
30
+ }
31
+ export {
32
+ keldraTransportAction,
33
+ wrapWalletClient
34
+ };