forked from Lilly-Protocol/lily-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsdk.ts
More file actions
149 lines (135 loc) · 5.47 KB
/
Copy pathsdk.ts
File metadata and controls
149 lines (135 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import { AgentClient } from './clients/agent-client';
import { IdentityClient } from './clients/identity-client';
import { PaymentClient } from './clients/payment-client';
import { SystemClient } from './clients/system-client';
import { WalletClient } from './clients/wallet-client';
import { resolveLilySdkConfig } from './config/resolve-config';
import type { LilySdkConfig, ResolvedLilySdkConfig } from './config/types';
import { createFetchHttpClient } from './http/fetch-http-client';
import type { HttpClient, HttpRequest } from './http/types';
import { SDK_VERSION } from './version';
export const DEFAULT_API_URL = 'https://api.lilyprotocol.com';
export class LilySdk {
public static readonly version: string = SDK_VERSION;
public readonly config: ResolvedLilySdkConfig;
public readonly httpClient: HttpClient;
public get http(): HttpClient {
return this.httpClient;
}
/**
* The HttpClient only when it was explicitly injected by the caller.
* Derived instances from `withConfig` reuse an injected client (so custom
* transport behavior is preserved), but never the default fetch client:
* that one is rebuilt from the merged config so `baseUrl`/credential
* overrides actually take effect on the transport.
*/
private readonly injectedHttpClient: HttpClient | undefined;
public readonly agents: AgentClient;
public readonly wallets: WalletClient;
public readonly payments: PaymentClient;
public readonly identity: IdentityClient;
public readonly system: SystemClient;
public constructor(config?: Partial<LilySdkConfig>, httpClient?: HttpClient) {
this.config = resolveLilySdkConfig(config ?? {});
this.httpClient = httpClient ?? createFetchHttpClient(this.config);
this.injectedHttpClient = httpClient;
this.agents = new AgentClient(this.httpClient);
this.wallets = new WalletClient(this.httpClient);
this.payments = new PaymentClient(this.httpClient);
this.identity = new IdentityClient(this.httpClient);
this.system = new SystemClient(this.httpClient);
}
/**
* Creates a LilySdk instance with sensible defaults from environment variables.
* Explicit options always take precedence over environment variables, which take
* precedence over the built-in default (https://api.lilyprotocol.com).
*
* Env vars read (in precedence order):
* - LILY_API_URL (preferred)
* - LILY_BASE_URL (fallback)
* - LILY_API_KEY
* - LILY_AUTH_TOKEN
*
* Note: Unlike the constructor, \create()\ never throws for a missing baseUrl.
* It silently falls back to \\DEFAULT_API_URL\\. Use the constructor if you
* need strict baseUrl validation.
*/
public static create(
options?: Partial<LilySdkConfig>,
httpClient?: HttpClient,
): LilySdk {
const baseUrl =
options?.baseUrl ??
(typeof process !== 'undefined'
? (process.env.LILY_API_URL ?? process.env.LILY_BASE_URL)
: undefined) ??
DEFAULT_API_URL;
const apiKey =
options?.apiKey ??
(typeof process !== 'undefined' ? process.env.LILY_API_KEY : undefined);
const authToken =
options?.authToken ??
(typeof process !== 'undefined'
? process.env.LILY_AUTH_TOKEN
: undefined);
const config: LilySdkConfig = {
baseUrl,
...(apiKey !== undefined ? { apiKey } : {}),
...(authToken !== undefined ? { authToken } : {}),
};
return new LilySdk(config, httpClient);
}
/**
* Sends a typed request using the SDK's shared HttpClient and returns the
* parsed response data, mirroring the client method API.
*/
public async request<TResponse, TRequest = unknown>(
request: HttpRequest<TRequest>,
): Promise<TResponse> {
const response = await this.httpClient.request<TResponse, TRequest>(
request,
);
return response.data;
}
/**
* Creates a new LilySdk instance with merged configuration.
* Useful for multi-tenant scenarios where credentials or baseUrl differ per tenant.
*
* When no custom fetch is overridden, a fresh HttpClient is built from the merged
* config so that baseUrl and auth changes take effect on the wire.
* When a custom fetch is explicitly provided in overrides, the parent's HttpClient
* is shared so that injection point is preserved.
*/
public withConfig(overrides: Partial<LilySdkConfig>): LilySdk {
const merged: LilySdkConfig = {
baseUrl: overrides.baseUrl ?? String(this.config.baseUrl),
timeoutMs: overrides.timeoutMs ?? this.config.timeoutMs,
retry: {
...this.config.retry,
...overrides.retry,
},
defaultHeaders: {
...this.config.defaultHeaders,
...overrides.defaultHeaders,
},
userAgent: overrides.userAgent ?? this.config.userAgent,
fetch: overrides.fetch ?? this.config.fetch,
...(overrides.apiKey !== undefined
? { apiKey: overrides.apiKey }
: this.config.apiKey !== undefined
? { apiKey: this.config.apiKey }
: {}),
...(overrides.authToken !== undefined
? { authToken: overrides.authToken }
: this.config.authToken !== undefined
? { authToken: this.config.authToken }
: {}),
};
// Reuse the transport only when the caller injected a custom HttpClient.
// The default fetch client is rebuilt from the merged config so that
// baseUrl/credential overrides are captured in the transport closure.
return this.injectedHttpClient !== undefined
? new LilySdk(merged, this.injectedHttpClient)
: new LilySdk(merged);
}
}