emblem-vault-ai-signers 0.1.6 → 0.1.8-experimental.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/http.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import type { EmblemRemoteConfig } from "./types.js";
2
- export declare function emblemPost<T = any>(path: string, body: any, { apiKey, baseUrl }: EmblemRemoteConfig): Promise<T>;
3
- export declare function emblemGet<T = any>(path: string, { apiKey, baseUrl }: EmblemRemoteConfig): Promise<T>;
2
+ export declare function emblemPost<T = any>(path: string, body: any, config: EmblemRemoteConfig): Promise<T>;
3
+ export declare function emblemGet<T = any>(path: string, config: EmblemRemoteConfig): Promise<T>;
package/dist/http.js CHANGED
@@ -19,12 +19,30 @@ function sanitizeErrorMessage(status, text) {
19
19
  }
20
20
  return errorMessage;
21
21
  }
22
- export async function emblemPost(path, body, { apiKey, baseUrl = "https://api.emblemvault.ai" }) {
22
+ async function resolveAuthHeaders(config) {
23
+ // Priority: custom headers -> apiKey -> jwt/getJwt/sdk
24
+ if (typeof config.getAuthHeaders === 'function') {
25
+ const h = await config.getAuthHeaders();
26
+ if (h && typeof h === 'object')
27
+ return h;
28
+ }
29
+ if (config.apiKey) {
30
+ return { 'x-api-key': config.apiKey };
31
+ }
32
+ const tok = config.jwt ?? (typeof config.getJwt === 'function' ? await config.getJwt() : undefined) ?? (config.sdk?.getSession()?.authToken ?? undefined);
33
+ if (tok) {
34
+ return { 'Authorization': `Bearer ${tok}` };
35
+ }
36
+ throw new Error('No authentication available: provide apiKey, jwt, getJwt(), getAuthHeaders(), or sdk');
37
+ }
38
+ export async function emblemPost(path, body, config) {
39
+ const baseUrl = config.baseUrl ?? "https://api.emblemvault.ai";
40
+ const authHeaders = await resolveAuthHeaders(config);
23
41
  const res = await fetch(`${baseUrl}${path}`, {
24
42
  method: "POST",
25
43
  headers: {
26
44
  "content-type": "application/json",
27
- "x-api-key": apiKey,
45
+ ...authHeaders,
28
46
  },
29
47
  body: JSON.stringify(body, (key, value) => typeof value === "bigint" ? value.toString() : value),
30
48
  });
@@ -34,12 +52,12 @@ export async function emblemPost(path, body, { apiKey, baseUrl = "https://api.em
34
52
  }
35
53
  return res.json();
36
54
  }
37
- export async function emblemGet(path, { apiKey, baseUrl = "https://api.emblemvault.ai" }) {
55
+ export async function emblemGet(path, config) {
56
+ const baseUrl = config.baseUrl ?? "https://api.emblemvault.ai";
57
+ const authHeaders = await resolveAuthHeaders(config);
38
58
  const res = await fetch(`${baseUrl}${path}`, {
39
59
  method: "GET",
40
- headers: {
41
- "x-api-key": apiKey,
42
- },
60
+ headers: authHeaders,
43
61
  });
44
62
  if (!res.ok) {
45
63
  const text = await res.text().catch(() => "");
package/dist/types.d.ts CHANGED
@@ -1,8 +1,23 @@
1
1
  export type Hex = `0x${string}`;
2
+ /** Optional auth providers */
3
+ export type EmblemAuthProvider = {
4
+ /** Static JWT to send as Authorization: Bearer */
5
+ jwt?: string;
6
+ /** Lazy JWT provider */
7
+ getJwt?: () => Promise<string | null | undefined> | string | null | undefined;
8
+ /** Custom headers provider (e.g., Authorization) */
9
+ getAuthHeaders?: () => Promise<Record<string, string>> | Record<string, string>;
10
+ /** SDK-like object exposing getSession() that returns { authToken? } */
11
+ sdk?: {
12
+ getSession: () => {
13
+ authToken?: string | null | undefined;
14
+ } | null | undefined;
15
+ };
16
+ };
2
17
  /** Config for Emblem remote signer */
3
- export type EmblemRemoteConfig = {
4
- /** x-api-key for your authenticate middleware */
5
- apiKey: string;
18
+ export type EmblemRemoteConfig = EmblemAuthProvider & {
19
+ /** x-api-key for your authenticate middleware (optional when JWT provided) */
20
+ apiKey?: string;
6
21
  /** Base URL for the Emblem signer API */
7
22
  baseUrl?: string;
8
23
  };
package/dist/utils.js CHANGED
@@ -37,6 +37,9 @@ export function normalizeTxForEmblem(tx) {
37
37
  // Remove fields commonly unsupported by legacy serializers
38
38
  delete out.type;
39
39
  delete out.accessList;
40
+ delete out.account;
41
+ delete out.chain;
42
+ delete out.from;
40
43
  return out;
41
44
  }
42
45
  export function isHexString(value) {
@@ -13,7 +13,7 @@ export declare function isNodeEnvironment(): boolean;
13
13
  /**
14
14
  * Validate API key format and warn about potential security issues
15
15
  */
16
- export declare function validateApiKey(apiKey: string, options?: {
16
+ export declare function validateApiKey(apiKey?: string, options?: {
17
17
  warnOnBrowser?: boolean;
18
18
  }): void;
19
19
  /**
@@ -19,24 +19,20 @@ export function isNodeEnvironment() {
19
19
  * Validate API key format and warn about potential security issues
20
20
  */
21
21
  export function validateApiKey(apiKey, options = {}) {
22
- if (!apiKey || typeof apiKey !== 'string') {
23
- throw new Error('apiKey is required and must be a string');
22
+ if (apiKey == null)
23
+ return; // optional
24
+ if (typeof apiKey !== 'string') {
25
+ throw new Error('apiKey must be a string when provided');
24
26
  }
25
27
  if (apiKey.trim() === '') {
26
28
  throw new Error('apiKey cannot be empty or whitespace');
27
29
  }
28
- // Warn if API key looks like it might be exposed in client-side code
29
30
  if (options.warnOnBrowser !== false && isBrowserEnvironment()) {
30
- console.warn('[Emblem Security Warning] API key is being used in a browser environment. ' +
31
- 'API keys should only be used server-side (Node.js). ' +
32
- 'Client-side usage exposes your API key to anyone who can view the page source. ' +
33
- 'To suppress this warning, pass { warnOnBrowser: false } to createEmblemClient().');
31
+ console.warn('[Emblem Security Warning] API key is being used in a browser environment. '
32
+ + 'Prefer JWT or a secure server-side usage. '
33
+ + 'To suppress this warning, pass { warnOnBrowser: false } to createEmblemClient().');
34
34
  }
35
- // Check for common mistakes
36
- if (apiKey.startsWith('pk_') || apiKey.startsWith('sk_')) {
37
- // Looks like a typical API key format - good
38
- }
39
- else if (apiKey.length < 16) {
35
+ if (!apiKey.startsWith('pk_') && !apiKey.startsWith('sk_') && apiKey.length < 16) {
40
36
  console.warn('[Emblem Security Warning] API key seems unusually short. Is this correct?');
41
37
  }
42
38
  }
@@ -93,7 +89,16 @@ export function toSafeNumber(value, fieldName) {
93
89
  * Comprehensive configuration validation
94
90
  */
95
91
  export function validateConfig(config) {
96
- // Validate API key
92
+ // Validate auth: require at least one method (apiKey, jwt, getJwt, getAuthHeaders, sdk)
93
+ const hasApiKey = !!config.apiKey;
94
+ const hasJwt = !!config.jwt;
95
+ const hasGetJwt = typeof config.getJwt === 'function';
96
+ const hasHeaders = typeof config.getAuthHeaders === 'function';
97
+ const hasSdk = !!config.sdk && typeof config.sdk.getSession === 'function';
98
+ if (!hasApiKey && !hasJwt && !hasGetJwt && !hasHeaders && !hasSdk) {
99
+ throw new Error('Authentication required: provide apiKey, jwt, getJwt(), getAuthHeaders(), or sdk');
100
+ }
101
+ // Validate API key if present
97
102
  validateApiKey(config.apiKey, { warnOnBrowser: config.warnOnBrowser });
98
103
  // Validate baseUrl if provided
99
104
  if (config.baseUrl) {
@@ -104,7 +109,7 @@ export function validateConfig(config) {
104
109
  console.log('[Emblem Security Debug]', {
105
110
  environment: isBrowserEnvironment() ? 'browser' : 'node',
106
111
  hasBaseUrl: !!config.baseUrl,
107
- apiKeyLength: config.apiKey.length,
112
+ apiKeyLength: config.apiKey ? config.apiKey.length : 0,
108
113
  timestamp: new Date().toISOString(),
109
114
  });
110
115
  }
package/dist/vault.js CHANGED
@@ -3,17 +3,17 @@ export async function fetchVaultInfo(config) {
3
3
  // Note: The server only supports POST for /vault/info
4
4
  // No need to try GET first, just use POST directly
5
5
  const data = await emblemPost("/vault/info", {}, config);
6
- // Validate response data
7
- if (!data.vaultId || !data.address || !data.evmAddress) {
6
+ // Validate required response data (vaultId + evmAddress are required for EVM)
7
+ if (!data || !data.vaultId || !data.evmAddress) {
8
8
  throw new Error('Invalid vault info response: missing required fields');
9
9
  }
10
- if (!data.evmAddress.startsWith('0x')) {
10
+ if (!String(data.evmAddress).startsWith('0x')) {
11
11
  throw new Error('Invalid evmAddress format in response');
12
12
  }
13
13
  return {
14
14
  vaultId: data.vaultId,
15
15
  tokenId: data.vaultId,
16
- address: data.address,
16
+ address: data.address || '', // Solana address may be absent; keep optional
17
17
  evmAddress: data.evmAddress,
18
18
  created_by: data.created_by,
19
19
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emblem-vault-ai-signers",
3
- "version": "0.1.6",
3
+ "version": "0.1.8-experimental.0",
4
4
  "description": "Emblem Vault remote signer adapters for viem and ethers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,7 +25,8 @@
25
25
  "test:ci": "vitest run --reporter=default",
26
26
  "test:integration": "vitest -c vitest.int.config.ts run --reporter=verbose",
27
27
  "test:all": "npm test && npm run test:integration",
28
- "release:patch": "npm version patch && npm run build && npm run test:all && npm publish"
28
+ "release:patch": "npm version patch && npm run build && npm run test:all && npm publish",
29
+ "release:experimental": "npm version prerelease --preid=experimental && npm run build && npm run test:all && npm publish --tag experimental"
29
30
  },
30
31
  "keywords": [
31
32
  "emblem",