@dominusnode/sdk 1.0.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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +679 -0
  3. package/dist/cjs/admin.d.ts +71 -0
  4. package/dist/cjs/admin.js +60 -0
  5. package/dist/cjs/auth.d.ts +47 -0
  6. package/dist/cjs/auth.js +46 -0
  7. package/dist/cjs/client.d.ts +56 -0
  8. package/dist/cjs/client.js +109 -0
  9. package/dist/cjs/constants.d.ts +8 -0
  10. package/dist/cjs/constants.js +11 -0
  11. package/dist/cjs/errors.d.ts +36 -0
  12. package/dist/cjs/errors.js +86 -0
  13. package/dist/cjs/http.d.ts +19 -0
  14. package/dist/cjs/http.js +195 -0
  15. package/dist/cjs/index.d.ts +30 -0
  16. package/dist/cjs/index.js +58 -0
  17. package/dist/cjs/keys.d.ts +27 -0
  18. package/dist/cjs/keys.js +22 -0
  19. package/dist/cjs/plans.d.ts +37 -0
  20. package/dist/cjs/plans.js +22 -0
  21. package/dist/cjs/proxy.d.ts +62 -0
  22. package/dist/cjs/proxy.js +71 -0
  23. package/dist/cjs/resources/agent-wallet.d.ts +52 -0
  24. package/dist/cjs/resources/agent-wallet.js +64 -0
  25. package/dist/cjs/resources/teams.d.ts +93 -0
  26. package/dist/cjs/resources/teams.js +82 -0
  27. package/dist/cjs/resources/wallet-auth.d.ts +66 -0
  28. package/dist/cjs/resources/wallet-auth.js +105 -0
  29. package/dist/cjs/resources/x402.d.ts +39 -0
  30. package/dist/cjs/resources/x402.js +25 -0
  31. package/dist/cjs/sessions.d.ts +15 -0
  32. package/dist/cjs/sessions.js +14 -0
  33. package/dist/cjs/slots.d.ts +9 -0
  34. package/dist/cjs/slots.js +19 -0
  35. package/dist/cjs/token-manager.d.ts +21 -0
  36. package/dist/cjs/token-manager.js +105 -0
  37. package/dist/cjs/types.d.ts +154 -0
  38. package/dist/cjs/types.js +2 -0
  39. package/dist/cjs/usage.d.ts +80 -0
  40. package/dist/cjs/usage.js +56 -0
  41. package/dist/cjs/wallet.d.ts +59 -0
  42. package/dist/cjs/wallet.js +56 -0
  43. package/dist/esm/admin.d.ts +71 -0
  44. package/dist/esm/admin.js +56 -0
  45. package/dist/esm/auth.d.ts +47 -0
  46. package/dist/esm/auth.js +42 -0
  47. package/dist/esm/client.d.ts +56 -0
  48. package/dist/esm/client.js +105 -0
  49. package/dist/esm/constants.d.ts +8 -0
  50. package/dist/esm/constants.js +8 -0
  51. package/dist/esm/errors.d.ts +36 -0
  52. package/dist/esm/errors.js +72 -0
  53. package/dist/esm/http.d.ts +19 -0
  54. package/dist/esm/http.js +191 -0
  55. package/dist/esm/index.d.ts +30 -0
  56. package/dist/esm/index.js +23 -0
  57. package/dist/esm/keys.d.ts +27 -0
  58. package/dist/esm/keys.js +18 -0
  59. package/dist/esm/plans.d.ts +37 -0
  60. package/dist/esm/plans.js +18 -0
  61. package/dist/esm/proxy.d.ts +62 -0
  62. package/dist/esm/proxy.js +67 -0
  63. package/dist/esm/resources/agent-wallet.d.ts +52 -0
  64. package/dist/esm/resources/agent-wallet.js +60 -0
  65. package/dist/esm/resources/teams.d.ts +93 -0
  66. package/dist/esm/resources/teams.js +78 -0
  67. package/dist/esm/resources/wallet-auth.d.ts +66 -0
  68. package/dist/esm/resources/wallet-auth.js +101 -0
  69. package/dist/esm/resources/x402.d.ts +39 -0
  70. package/dist/esm/resources/x402.js +21 -0
  71. package/dist/esm/sessions.d.ts +15 -0
  72. package/dist/esm/sessions.js +10 -0
  73. package/dist/esm/slots.d.ts +9 -0
  74. package/dist/esm/slots.js +15 -0
  75. package/dist/esm/token-manager.d.ts +21 -0
  76. package/dist/esm/token-manager.js +101 -0
  77. package/dist/esm/types.d.ts +154 -0
  78. package/dist/esm/types.js +1 -0
  79. package/dist/esm/usage.d.ts +80 -0
  80. package/dist/esm/usage.js +52 -0
  81. package/dist/esm/wallet.d.ts +59 -0
  82. package/dist/esm/wallet.js +52 -0
  83. package/dist/tsconfig.tsbuildinfo +1 -0
  84. package/package.json +31 -0
@@ -0,0 +1,67 @@
1
+ import { DEFAULT_PROXY_HOST, DEFAULT_HTTP_PROXY_PORT, DEFAULT_SOCKS5_PROXY_PORT, } from "./constants.js";
2
+ export class ProxyResource {
3
+ http;
4
+ proxyHost;
5
+ httpPort;
6
+ socks5Port;
7
+ constructor(http, config) {
8
+ this.http = http;
9
+ this.proxyHost = config.proxyHost ?? DEFAULT_PROXY_HOST;
10
+ // Validate proxyHost to prevent URL injection via crafted hostnames
11
+ if (/[\s\/\\@?#]/.test(this.proxyHost)) {
12
+ throw new Error("proxyHost contains invalid characters");
13
+ }
14
+ this.httpPort = config.httpProxyPort ?? DEFAULT_HTTP_PROXY_PORT;
15
+ this.socks5Port = config.socks5ProxyPort ?? DEFAULT_SOCKS5_PROXY_PORT;
16
+ }
17
+ /**
18
+ * Build a proxy URL string for use with HTTP clients.
19
+ *
20
+ * The returned URL includes authentication via the username field.
21
+ * Geo-targeting and sticky sessions are encoded in the username portion
22
+ * following Dominus Node proxy conventions.
23
+ *
24
+ * @param apiKey - The API key to authenticate proxy requests.
25
+ * @param opts - Optional targeting parameters (protocol, country, etc.).
26
+ * @returns A fully-formed proxy URL string.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * const url = client.proxy.buildUrl("dn_live_abc123");
31
+ * // => "http://user:dn_live_abc123@proxy.dominusnode.com:8080"
32
+ *
33
+ * const socksUrl = client.proxy.buildUrl("dn_live_abc123", { protocol: "socks5", country: "US" });
34
+ * // => "socks5://user-country-US:dn_live_abc123@proxy.dominusnode.com:1080"
35
+ * ```
36
+ */
37
+ buildUrl(apiKey, opts) {
38
+ const protocol = opts?.protocol ?? "http";
39
+ const port = protocol === "socks5" ? this.socks5Port : this.httpPort;
40
+ // Build username with geo-targeting parameters (URL-encoded to prevent injection)
41
+ const userParts = ["user"];
42
+ if (opts?.country)
43
+ userParts.push(`country-${encodeURIComponent(opts.country)}`);
44
+ if (opts?.state)
45
+ userParts.push(`state-${encodeURIComponent(opts.state)}`);
46
+ if (opts?.city)
47
+ userParts.push(`city-${encodeURIComponent(opts.city)}`);
48
+ if (opts?.asn)
49
+ userParts.push(`asn-${encodeURIComponent(String(opts.asn))}`);
50
+ if (opts?.sessionId)
51
+ userParts.push(`session-${encodeURIComponent(opts.sessionId)}`);
52
+ const username = userParts.join("-");
53
+ return `${protocol}://${username}:${encodeURIComponent(apiKey)}@${this.proxyHost}:${port}`;
54
+ }
55
+ /** Get public proxy health status (does not require authentication). */
56
+ async getHealth() {
57
+ return this.http.get("/api/proxy/health", false);
58
+ }
59
+ /** Get detailed proxy status including provider info (requires authentication). */
60
+ async getStatus() {
61
+ return this.http.get("/api/proxy/status");
62
+ }
63
+ /** Get proxy server configuration (requires authentication). */
64
+ async getConfig() {
65
+ return this.http.get("/api/proxy/config");
66
+ }
67
+ }
@@ -0,0 +1,52 @@
1
+ import type { HttpClient } from "../http.js";
2
+ export interface AgenticWallet {
3
+ id: string;
4
+ label: string;
5
+ balanceCents: number;
6
+ spendingLimitCents: number;
7
+ dailyLimitCents: number | null;
8
+ allowedDomains: string[] | null;
9
+ status: string;
10
+ createdAt: string;
11
+ }
12
+ export interface AgenticWalletTransaction {
13
+ id: string;
14
+ walletId: string;
15
+ type: string;
16
+ amountCents: number;
17
+ description: string;
18
+ sessionId: string | null;
19
+ createdAt: string;
20
+ }
21
+ export interface AgenticWalletListResponse {
22
+ wallets: AgenticWallet[];
23
+ }
24
+ export interface AgenticWalletFundResponse {
25
+ transaction: AgenticWalletTransaction;
26
+ }
27
+ export interface AgenticWalletTransactionsResponse {
28
+ transactions: AgenticWalletTransaction[];
29
+ }
30
+ export interface AgenticWalletDeleteResponse {
31
+ deleted: boolean;
32
+ refundedCents: number;
33
+ }
34
+ export declare class AgenticWalletResource {
35
+ private http;
36
+ constructor(http: HttpClient);
37
+ create(label: string, spendingLimitCents?: number, options?: {
38
+ dailyLimitCents?: number | null;
39
+ allowedDomains?: string[] | null;
40
+ }): Promise<AgenticWallet>;
41
+ list(): Promise<AgenticWalletListResponse>;
42
+ get(walletId: string): Promise<AgenticWallet>;
43
+ fund(walletId: string, amountCents: number): Promise<AgenticWalletFundResponse>;
44
+ updateWalletPolicy(walletId: string, policy: {
45
+ dailyLimitCents?: number | null;
46
+ allowedDomains?: string[] | null;
47
+ }): Promise<AgenticWallet>;
48
+ transactions(walletId: string, limit?: number, offset?: number): Promise<AgenticWalletTransactionsResponse>;
49
+ freeze(walletId: string): Promise<AgenticWallet>;
50
+ unfreeze(walletId: string): Promise<AgenticWallet>;
51
+ delete(walletId: string): Promise<AgenticWalletDeleteResponse>;
52
+ }
@@ -0,0 +1,60 @@
1
+ export class AgenticWalletResource {
2
+ http;
3
+ constructor(http) {
4
+ this.http = http;
5
+ }
6
+ async create(label, spendingLimitCents = 10000, options) {
7
+ if (!Number.isInteger(spendingLimitCents) || spendingLimitCents < 0 || spendingLimitCents > 2_147_483_647) {
8
+ throw new Error("spendingLimitCents must be a non-negative integer <= 2,147,483,647");
9
+ }
10
+ if (options?.dailyLimitCents !== undefined && options.dailyLimitCents !== null) {
11
+ if (!Number.isInteger(options.dailyLimitCents) || options.dailyLimitCents < 0 || options.dailyLimitCents > 2_147_483_647) {
12
+ throw new Error("dailyLimitCents must be a non-negative integer <= 2,147,483,647");
13
+ }
14
+ }
15
+ const body = { label, spendingLimitCents };
16
+ if (options?.dailyLimitCents !== undefined)
17
+ body.dailyLimitCents = options.dailyLimitCents;
18
+ if (options?.allowedDomains !== undefined)
19
+ body.allowedDomains = options.allowedDomains;
20
+ return this.http.post("/api/agent-wallet", body);
21
+ }
22
+ async list() {
23
+ return this.http.get("/api/agent-wallet");
24
+ }
25
+ async get(walletId) {
26
+ return this.http.get(`/api/agent-wallet/${encodeURIComponent(walletId)}`);
27
+ }
28
+ async fund(walletId, amountCents) {
29
+ if (!Number.isInteger(amountCents) || amountCents <= 0 || amountCents > 2_147_483_647) {
30
+ throw new Error("amountCents must be a positive integer <= 2,147,483,647");
31
+ }
32
+ return this.http.post(`/api/agent-wallet/${encodeURIComponent(walletId)}/fund`, { amountCents });
33
+ }
34
+ async updateWalletPolicy(walletId, policy) {
35
+ if (policy.dailyLimitCents !== undefined && policy.dailyLimitCents !== null) {
36
+ if (!Number.isInteger(policy.dailyLimitCents) || policy.dailyLimitCents < 0 || policy.dailyLimitCents > 2_147_483_647) {
37
+ throw new Error("dailyLimitCents must be a non-negative integer <= 2,147,483,647");
38
+ }
39
+ }
40
+ return this.http.patch(`/api/agent-wallet/${encodeURIComponent(walletId)}/policy`, policy);
41
+ }
42
+ async transactions(walletId, limit, offset) {
43
+ const params = new URLSearchParams();
44
+ if (limit !== undefined)
45
+ params.set("limit", String(limit));
46
+ if (offset !== undefined)
47
+ params.set("offset", String(offset));
48
+ const qs = params.toString();
49
+ return this.http.get(`/api/agent-wallet/${encodeURIComponent(walletId)}/transactions${qs ? `?${qs}` : ""}`);
50
+ }
51
+ async freeze(walletId) {
52
+ return this.http.post(`/api/agent-wallet/${encodeURIComponent(walletId)}/freeze`, {});
53
+ }
54
+ async unfreeze(walletId) {
55
+ return this.http.post(`/api/agent-wallet/${encodeURIComponent(walletId)}/unfreeze`, {});
56
+ }
57
+ async delete(walletId) {
58
+ return this.http.delete(`/api/agent-wallet/${encodeURIComponent(walletId)}`);
59
+ }
60
+ }
@@ -0,0 +1,93 @@
1
+ import type { HttpClient } from "../http.js";
2
+ export interface Team {
3
+ id: string;
4
+ name: string;
5
+ ownerId: string;
6
+ maxMembers: number;
7
+ status: string;
8
+ balanceCents: number;
9
+ createdAt: string;
10
+ }
11
+ export interface TeamMember {
12
+ id: string;
13
+ teamId: string;
14
+ userId: string;
15
+ email: string;
16
+ role: string;
17
+ joinedAt: string;
18
+ }
19
+ export interface TeamInvite {
20
+ id: string;
21
+ teamId: string;
22
+ email: string;
23
+ role: string;
24
+ token: string;
25
+ expiresAt: string;
26
+ createdAt: string;
27
+ }
28
+ export interface TeamKey {
29
+ id: string;
30
+ keyPrefix: string;
31
+ label: string;
32
+ createdAt: string;
33
+ }
34
+ export interface TeamKeyCreateResponse {
35
+ id: string;
36
+ key: string;
37
+ keyPrefix: string;
38
+ label: string;
39
+ }
40
+ export interface TeamListResponse {
41
+ teams: Team[];
42
+ }
43
+ export interface TeamDeleteResponse {
44
+ refundedCents: number;
45
+ }
46
+ export interface TeamFundResponse {
47
+ transaction: TeamTransaction;
48
+ }
49
+ export interface TeamTransaction {
50
+ id: string;
51
+ teamId: string;
52
+ type: string;
53
+ amountCents: number;
54
+ description: string;
55
+ createdAt: string;
56
+ }
57
+ export interface TeamTransactionsResponse {
58
+ transactions: TeamTransaction[];
59
+ }
60
+ export interface TeamMembersResponse {
61
+ members: TeamMember[];
62
+ }
63
+ export interface TeamInvitesResponse {
64
+ invites: TeamInvite[];
65
+ }
66
+ export interface TeamKeysResponse {
67
+ keys: TeamKey[];
68
+ }
69
+ export declare class TeamsResource {
70
+ private http;
71
+ constructor(http: HttpClient);
72
+ create(name: string, maxMembers?: number): Promise<Team>;
73
+ list(): Promise<Team[]>;
74
+ get(teamId: string): Promise<Team>;
75
+ update(teamId: string, updates: {
76
+ name?: string;
77
+ maxMembers?: number;
78
+ }): Promise<Team>;
79
+ delete(teamId: string): Promise<TeamDeleteResponse>;
80
+ fundWallet(teamId: string, amountCents: number): Promise<TeamFundResponse>;
81
+ getTransactions(teamId: string, limit?: number, offset?: number): Promise<TeamTransactionsResponse>;
82
+ listMembers(teamId: string): Promise<TeamMembersResponse>;
83
+ addMember(teamId: string, email: string, role?: string): Promise<TeamMember>;
84
+ updateMemberRole(teamId: string, userId: string, role: string): Promise<TeamMember>;
85
+ removeMember(teamId: string, userId: string): Promise<void>;
86
+ createInvite(teamId: string, email: string, role?: string): Promise<TeamInvite>;
87
+ listInvites(teamId: string): Promise<TeamInvitesResponse>;
88
+ cancelInvite(teamId: string, inviteId: string): Promise<void>;
89
+ acceptInvite(token: string): Promise<TeamMember>;
90
+ createKey(teamId: string, label: string): Promise<TeamKeyCreateResponse>;
91
+ listKeys(teamId: string): Promise<TeamKeysResponse>;
92
+ revokeKey(teamId: string, keyId: string): Promise<void>;
93
+ }
@@ -0,0 +1,78 @@
1
+ export class TeamsResource {
2
+ http;
3
+ constructor(http) {
4
+ this.http = http;
5
+ }
6
+ async create(name, maxMembers) {
7
+ const body = { name };
8
+ if (maxMembers !== undefined)
9
+ body.maxMembers = maxMembers;
10
+ return this.http.post("/api/teams", body);
11
+ }
12
+ async list() {
13
+ return this.http.get("/api/teams");
14
+ }
15
+ async get(teamId) {
16
+ return this.http.get(`/api/teams/${encodeURIComponent(teamId)}`);
17
+ }
18
+ async update(teamId, updates) {
19
+ return this.http.patch(`/api/teams/${encodeURIComponent(teamId)}`, updates);
20
+ }
21
+ async delete(teamId) {
22
+ return this.http.delete(`/api/teams/${encodeURIComponent(teamId)}`);
23
+ }
24
+ async fundWallet(teamId, amountCents) {
25
+ if (!Number.isInteger(amountCents) || amountCents <= 0 || amountCents > 2_147_483_647) {
26
+ throw new Error("amountCents must be a positive integer <= 2,147,483,647");
27
+ }
28
+ return this.http.post(`/api/teams/${encodeURIComponent(teamId)}/wallet/fund`, { amountCents });
29
+ }
30
+ async getTransactions(teamId, limit, offset) {
31
+ const params = new URLSearchParams();
32
+ if (limit !== undefined)
33
+ params.set("limit", String(limit));
34
+ if (offset !== undefined)
35
+ params.set("offset", String(offset));
36
+ const qs = params.toString();
37
+ return this.http.get(`/api/teams/${encodeURIComponent(teamId)}/wallet/transactions${qs ? `?${qs}` : ""}`);
38
+ }
39
+ async listMembers(teamId) {
40
+ return this.http.get(`/api/teams/${encodeURIComponent(teamId)}/members`);
41
+ }
42
+ async addMember(teamId, email, role) {
43
+ const body = { email };
44
+ if (role !== undefined)
45
+ body.role = role;
46
+ return this.http.post(`/api/teams/${encodeURIComponent(teamId)}/members`, body);
47
+ }
48
+ async updateMemberRole(teamId, userId, role) {
49
+ return this.http.patch(`/api/teams/${encodeURIComponent(teamId)}/members/${encodeURIComponent(userId)}`, { role });
50
+ }
51
+ async removeMember(teamId, userId) {
52
+ await this.http.delete(`/api/teams/${encodeURIComponent(teamId)}/members/${encodeURIComponent(userId)}`);
53
+ }
54
+ async createInvite(teamId, email, role) {
55
+ const body = { email };
56
+ if (role !== undefined)
57
+ body.role = role;
58
+ return this.http.post(`/api/teams/${encodeURIComponent(teamId)}/invites`, body);
59
+ }
60
+ async listInvites(teamId) {
61
+ return this.http.get(`/api/teams/${encodeURIComponent(teamId)}/invites`);
62
+ }
63
+ async cancelInvite(teamId, inviteId) {
64
+ await this.http.delete(`/api/teams/${encodeURIComponent(teamId)}/invites/${encodeURIComponent(inviteId)}`);
65
+ }
66
+ async acceptInvite(token) {
67
+ return this.http.post(`/api/teams/invites/${encodeURIComponent(token)}/accept`, {});
68
+ }
69
+ async createKey(teamId, label) {
70
+ return this.http.post(`/api/teams/${encodeURIComponent(teamId)}/keys`, { label });
71
+ }
72
+ async listKeys(teamId) {
73
+ return this.http.get(`/api/teams/${encodeURIComponent(teamId)}/keys`);
74
+ }
75
+ async revokeKey(teamId, keyId) {
76
+ await this.http.delete(`/api/teams/${encodeURIComponent(teamId)}/keys/${encodeURIComponent(keyId)}`);
77
+ }
78
+ }
@@ -0,0 +1,66 @@
1
+ import type { HttpClient } from "../http.js";
2
+ import type { TokenManager } from "../token-manager.js";
3
+ import type { User } from "../types.js";
4
+ export interface WalletChallenge {
5
+ challenge: string;
6
+ expiresAt: string;
7
+ }
8
+ export interface WalletVerifyResult {
9
+ token: string;
10
+ refreshToken: string;
11
+ user: User;
12
+ /** When true, the user must complete MFA before authentication is granted. */
13
+ mfaRequired?: boolean;
14
+ /** Challenge token to pass to auth.verifyMfa() when mfaRequired is true. */
15
+ mfaChallengeToken?: string;
16
+ }
17
+ export interface WalletLinkResult {
18
+ success: boolean;
19
+ walletAddress: string;
20
+ }
21
+ /**
22
+ * Wallet-based authentication using EIP-191 signed messages.
23
+ *
24
+ * Allows Ethereum wallet holders to authenticate by signing a server-issued
25
+ * challenge message. Supports account creation, login, and linking a wallet
26
+ * to an existing account.
27
+ */
28
+ export declare class WalletAuthResource {
29
+ private http;
30
+ private tokenManager;
31
+ constructor(http: HttpClient, tokenManager: TokenManager);
32
+ /**
33
+ * Request a signature challenge for the given Ethereum address.
34
+ *
35
+ * The returned challenge must be signed with the wallet's private key
36
+ * and submitted via `verify()` to complete authentication.
37
+ *
38
+ * This endpoint does not require authentication.
39
+ */
40
+ challenge(address: string): Promise<WalletChallenge>;
41
+ /**
42
+ * Submit a signed challenge to create an account or log in.
43
+ *
44
+ * If the address is not yet associated with an account, a new one is created.
45
+ * Returns JWT tokens and user information on success.
46
+ * Tokens are automatically stored for subsequent authenticated requests.
47
+ *
48
+ * This endpoint does not require authentication.
49
+ *
50
+ * @param address - Ethereum address (0x-prefixed, 40 hex chars)
51
+ * @param signature - EIP-191 signature of the challenge message
52
+ * @param challenge - Optional: the challenge string (server looks up internally)
53
+ */
54
+ verify(address: string, signature: string, challenge?: string): Promise<WalletVerifyResult>;
55
+ /**
56
+ * Link an Ethereum wallet to the currently authenticated account.
57
+ *
58
+ * Requires JWT authentication. The challenge must have been previously
59
+ * obtained via `challenge()` and signed with the wallet.
60
+ *
61
+ * @param address - Ethereum address
62
+ * @param signature - EIP-191 signature
63
+ * @param challenge - Optional: the challenge string
64
+ */
65
+ link(address: string, signature: string, challenge?: string): Promise<WalletLinkResult>;
66
+ }
@@ -0,0 +1,101 @@
1
+ // Ethereum address validation: 0x followed by 40 hex characters
2
+ const ETH_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
3
+ // EIP-191 signature format: 0x prefix + 130 hex chars (65 bytes)
4
+ const EIP191_SIGNATURE_RE = /^0x[0-9a-fA-F]{130}$/;
5
+ const MAX_SIGNATURE_LENGTH = 200;
6
+ function validateAddress(address) {
7
+ if (!address || typeof address !== "string") {
8
+ throw new Error("address is required and must be a string");
9
+ }
10
+ if (!ETH_ADDRESS_RE.test(address)) {
11
+ throw new Error("address must be a valid Ethereum address (0x followed by 40 hex characters)");
12
+ }
13
+ }
14
+ function validateSignature(signature) {
15
+ if (!signature || typeof signature !== "string") {
16
+ throw new Error("signature is required and must be a string");
17
+ }
18
+ // Max length check before regex
19
+ if (signature.length > MAX_SIGNATURE_LENGTH) {
20
+ throw new Error(`signature must not exceed ${MAX_SIGNATURE_LENGTH} characters`);
21
+ }
22
+ // EIP-191 format validation
23
+ if (!EIP191_SIGNATURE_RE.test(signature)) {
24
+ throw new Error("signature must be a valid EIP-191 signature (0x followed by 130 hex characters)");
25
+ }
26
+ }
27
+ /**
28
+ * Wallet-based authentication using EIP-191 signed messages.
29
+ *
30
+ * Allows Ethereum wallet holders to authenticate by signing a server-issued
31
+ * challenge message. Supports account creation, login, and linking a wallet
32
+ * to an existing account.
33
+ */
34
+ export class WalletAuthResource {
35
+ http;
36
+ tokenManager;
37
+ constructor(http, tokenManager) {
38
+ this.http = http;
39
+ this.tokenManager = tokenManager;
40
+ }
41
+ /**
42
+ * Request a signature challenge for the given Ethereum address.
43
+ *
44
+ * The returned challenge must be signed with the wallet's private key
45
+ * and submitted via `verify()` to complete authentication.
46
+ *
47
+ * This endpoint does not require authentication.
48
+ */
49
+ async challenge(address) {
50
+ validateAddress(address);
51
+ return this.http.post("/api/auth/wallet/challenge", { address }, false);
52
+ }
53
+ /**
54
+ * Submit a signed challenge to create an account or log in.
55
+ *
56
+ * If the address is not yet associated with an account, a new one is created.
57
+ * Returns JWT tokens and user information on success.
58
+ * Tokens are automatically stored for subsequent authenticated requests.
59
+ *
60
+ * This endpoint does not require authentication.
61
+ *
62
+ * @param address - Ethereum address (0x-prefixed, 40 hex chars)
63
+ * @param signature - EIP-191 signature of the challenge message
64
+ * @param challenge - Optional: the challenge string (server looks up internally)
65
+ */
66
+ async verify(address, signature, challenge) {
67
+ validateAddress(address);
68
+ validateSignature(signature);
69
+ const body = { address, signature };
70
+ if (challenge)
71
+ body.challenge = challenge;
72
+ const result = await this.http.post("/api/auth/wallet/verify", body, false);
73
+ // Detect MFA-required response — don't store tokens, surface to caller
74
+ if (result.mfaRequired) {
75
+ return result;
76
+ }
77
+ // Store tokens after verify (matching Python/Go/Java SDKs)
78
+ if (result.token && result.refreshToken) {
79
+ this.tokenManager.setTokens(result.token, result.refreshToken);
80
+ }
81
+ return result;
82
+ }
83
+ /**
84
+ * Link an Ethereum wallet to the currently authenticated account.
85
+ *
86
+ * Requires JWT authentication. The challenge must have been previously
87
+ * obtained via `challenge()` and signed with the wallet.
88
+ *
89
+ * @param address - Ethereum address
90
+ * @param signature - EIP-191 signature
91
+ * @param challenge - Optional: the challenge string
92
+ */
93
+ async link(address, signature, challenge) {
94
+ validateAddress(address);
95
+ validateSignature(signature);
96
+ const body = { address, signature };
97
+ if (challenge)
98
+ body.challenge = challenge;
99
+ return this.http.post("/api/auth/wallet/link", body);
100
+ }
101
+ }
@@ -0,0 +1,39 @@
1
+ import type { HttpClient } from "../http.js";
2
+ export interface X402Facilitator {
3
+ address: string;
4
+ chain: string;
5
+ network: string;
6
+ }
7
+ export interface X402Pricing {
8
+ perRequestCents: number;
9
+ perGbCents: number;
10
+ currency: string;
11
+ }
12
+ export interface X402Info {
13
+ supported: boolean;
14
+ enabled: boolean;
15
+ protocol: string;
16
+ version: string;
17
+ facilitators: X402Facilitator[];
18
+ pricing: X402Pricing;
19
+ currencies: string[];
20
+ walletType: string;
21
+ agenticWallets: boolean;
22
+ }
23
+ /**
24
+ * x402 (HTTP 402 Payment Required) protocol information.
25
+ *
26
+ * Provides details about x402 micropayment support, facilitator addresses,
27
+ * pricing, and supported chains/currencies for AI agent payments.
28
+ */
29
+ export declare class X402Resource {
30
+ private http;
31
+ constructor(http: HttpClient);
32
+ /**
33
+ * Get x402 protocol information including facilitator details,
34
+ * pricing, supported chains, and currencies.
35
+ *
36
+ * This endpoint does not require authentication.
37
+ */
38
+ getInfo(): Promise<X402Info>;
39
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * x402 (HTTP 402 Payment Required) protocol information.
3
+ *
4
+ * Provides details about x402 micropayment support, facilitator addresses,
5
+ * pricing, and supported chains/currencies for AI agent payments.
6
+ */
7
+ export class X402Resource {
8
+ http;
9
+ constructor(http) {
10
+ this.http = http;
11
+ }
12
+ /**
13
+ * Get x402 protocol information including facilitator details,
14
+ * pricing, supported chains, and currencies.
15
+ *
16
+ * This endpoint does not require authentication.
17
+ */
18
+ async getInfo() {
19
+ return this.http.get("/api/x402/info", false);
20
+ }
21
+ }
@@ -0,0 +1,15 @@
1
+ import type { HttpClient } from "./http.js";
2
+ export interface ActiveSessionEntry {
3
+ id: string;
4
+ startedAt: string;
5
+ status: string;
6
+ }
7
+ export interface ActiveSessionsResponse {
8
+ sessions: ActiveSessionEntry[];
9
+ }
10
+ export declare class SessionsResource {
11
+ private http;
12
+ constructor(http: HttpClient);
13
+ /** Get all active proxy sessions for the authenticated user. */
14
+ getActive(): Promise<ActiveSessionsResponse>;
15
+ }
@@ -0,0 +1,10 @@
1
+ export class SessionsResource {
2
+ http;
3
+ constructor(http) {
4
+ this.http = http;
5
+ }
6
+ /** Get all active proxy sessions for the authenticated user. */
7
+ async getActive() {
8
+ return this.http.get("/api/sessions/active");
9
+ }
10
+ }
@@ -0,0 +1,9 @@
1
+ import type { HttpClient } from "./http.js";
2
+ import type { SlotsInfo, WaitlistJoinResult, WaitlistCount } from "./types.js";
3
+ export declare class SlotsResource {
4
+ private http;
5
+ constructor(http: HttpClient);
6
+ getSlots(): Promise<SlotsInfo>;
7
+ joinWaitlist(email: string): Promise<WaitlistJoinResult>;
8
+ getWaitlistCount(): Promise<WaitlistCount>;
9
+ }
@@ -0,0 +1,15 @@
1
+ export class SlotsResource {
2
+ http;
3
+ constructor(http) {
4
+ this.http = http;
5
+ }
6
+ async getSlots() {
7
+ return this.http.get("/api/slots", false);
8
+ }
9
+ async joinWaitlist(email) {
10
+ return this.http.post("/api/waitlist/join", { email }, false);
11
+ }
12
+ async getWaitlistCount() {
13
+ return this.http.get("/api/waitlist/count", false);
14
+ }
15
+ }
@@ -0,0 +1,21 @@
1
+ export declare class TokenManager {
2
+ private accessToken;
3
+ private refreshTokenValue;
4
+ private refreshPromise;
5
+ private refreshFn;
6
+ setTokens(access: string, refresh?: string): void;
7
+ setRefreshFunction(fn: (refreshToken: string) => Promise<{
8
+ accessToken: string;
9
+ refreshToken?: string;
10
+ }>): void;
11
+ getAccessToken(): string | null;
12
+ getRefreshToken(): string | null;
13
+ isExpired(token: string): boolean;
14
+ getValidToken(): Promise<string>;
15
+ /**
16
+ * Force a token refresh regardless of expiry state.
17
+ * Used after a 401 response to avoid re-using a rejected token.
18
+ */
19
+ forceRefresh(): Promise<string>;
20
+ clear(): void;
21
+ }