@tinycloud/node-sdk 1.0.1 → 1.2.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 (48) hide show
  1. package/dist/index.cjs +18926 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.d.cts +1007 -0
  4. package/dist/index.d.ts +991 -36
  5. package/dist/index.js +18951 -72
  6. package/dist/index.js.map +1 -1
  7. package/package.json +6 -5
  8. package/dist/DelegatedAccess.d.ts +0 -33
  9. package/dist/DelegatedAccess.d.ts.map +0 -1
  10. package/dist/DelegatedAccess.js +0 -61
  11. package/dist/DelegatedAccess.js.map +0 -1
  12. package/dist/TinyCloudNode.d.ts +0 -441
  13. package/dist/TinyCloudNode.d.ts.map +0 -1
  14. package/dist/TinyCloudNode.js +0 -987
  15. package/dist/TinyCloudNode.js.map +0 -1
  16. package/dist/authorization/NodeUserAuthorization.d.ts +0 -200
  17. package/dist/authorization/NodeUserAuthorization.d.ts.map +0 -1
  18. package/dist/authorization/NodeUserAuthorization.js +0 -516
  19. package/dist/authorization/NodeUserAuthorization.js.map +0 -1
  20. package/dist/authorization/strategies.d.ts +0 -57
  21. package/dist/authorization/strategies.d.ts.map +0 -1
  22. package/dist/authorization/strategies.js +0 -15
  23. package/dist/authorization/strategies.js.map +0 -1
  24. package/dist/delegation.d.ts +0 -35
  25. package/dist/delegation.d.ts.map +0 -1
  26. package/dist/delegation.js +0 -21
  27. package/dist/delegation.js.map +0 -1
  28. package/dist/index.d.ts.map +0 -1
  29. package/dist/keys/WasmKeyProvider.d.ts +0 -101
  30. package/dist/keys/WasmKeyProvider.d.ts.map +0 -1
  31. package/dist/keys/WasmKeyProvider.js +0 -113
  32. package/dist/keys/WasmKeyProvider.js.map +0 -1
  33. package/dist/keys/index.d.ts +0 -7
  34. package/dist/keys/index.d.ts.map +0 -1
  35. package/dist/keys/index.js +0 -7
  36. package/dist/keys/index.js.map +0 -1
  37. package/dist/signers/PrivateKeySigner.d.ts +0 -47
  38. package/dist/signers/PrivateKeySigner.d.ts.map +0 -1
  39. package/dist/signers/PrivateKeySigner.js +0 -89
  40. package/dist/signers/PrivateKeySigner.js.map +0 -1
  41. package/dist/storage/FileSessionStorage.d.ts +0 -59
  42. package/dist/storage/FileSessionStorage.d.ts.map +0 -1
  43. package/dist/storage/FileSessionStorage.js +0 -148
  44. package/dist/storage/FileSessionStorage.js.map +0 -1
  45. package/dist/storage/MemorySessionStorage.d.ts +0 -49
  46. package/dist/storage/MemorySessionStorage.d.ts.map +0 -1
  47. package/dist/storage/MemorySessionStorage.js +0 -88
  48. package/dist/storage/MemorySessionStorage.js.map +0 -1
@@ -1,21 +0,0 @@
1
- /**
2
- * Serialize a PortableDelegation for transport (e.g., over network).
3
- */
4
- export function serializeDelegation(delegation) {
5
- return JSON.stringify({
6
- ...delegation,
7
- expiry: delegation.expiry.toISOString(),
8
- });
9
- }
10
- /**
11
- * Deserialize a PortableDelegation from transport.
12
- */
13
- export function deserializeDelegation(data) {
14
- const parsed = JSON.parse(data);
15
- return {
16
- ...parsed,
17
- cid: parsed.cid,
18
- expiry: new Date(parsed.expiry),
19
- };
20
- }
21
- //# sourceMappingURL=delegation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"delegation.js","sourceRoot":"","sources":["../src/delegation.ts"],"names":[],"mappings":"AA8BA;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAA8B;IAChE,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,GAAG,UAAU;QACb,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE;KACxC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO;QACL,GAAG,MAAM;QACT,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,MAAM,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;KAChC,CAAC;AACJ,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,EACL,SAAS,EACT,eAAe,EACf,OAAO,EACP,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,SAAS,EACT,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGlE,OAAO,EACL,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,uCAAuC,CAAC;AAG/C,OAAO,EAEL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EAEnB,wBAAwB,EACxB,YAAY,GACb,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,UAAU,EACV,SAAS,EACT,eAAe,EACf,UAAU,EAEV,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAEL,iBAAiB,EACjB,uBAAuB,EAEvB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,WAAW,EAEX,UAAU,EACV,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EAEjB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EAEnB,GAAG,EACH,OAAO,EACP,OAAO,EACP,eAAe,EACf,gBAAgB,EAEhB,cAAc,EACd,SAAS,EAET,WAAW,EACX,SAAS,EACT,aAAa,EACb,aAAa,EACb,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,aAAa,EAEb,KAAK,EACL,MAAM,EACN,WAAW,EACX,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,cAAc,EACd,aAAa,GACd,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC"}
@@ -1,101 +0,0 @@
1
- /**
2
- * WasmKeyProvider - KeyProvider implementation using WASM session manager.
3
- *
4
- * This provider wraps the SessionManager from node-sdk-wasm to provide
5
- * cryptographic key operations required by the SharingService.
6
- *
7
- * @packageDocumentation
8
- */
9
- import type { KeyProvider, JWK } from "@tinycloud/sdk-core";
10
- import type { TCWSessionManager as SessionManager } from "@tinycloud/node-sdk-wasm";
11
- /**
12
- * Configuration for WasmKeyProvider.
13
- */
14
- export interface WasmKeyProviderConfig {
15
- /**
16
- * The WASM session manager instance.
17
- * Must be created before constructing the KeyProvider.
18
- */
19
- sessionManager: SessionManager;
20
- }
21
- /**
22
- * KeyProvider implementation that wraps the WASM session manager.
23
- *
24
- * This allows the SharingService to create new session keys for sharing links
25
- * using the same cryptographic operations as the main session management.
26
- *
27
- * @example
28
- * ```typescript
29
- * import { SessionManager } from "@tinycloud/node-sdk-wasm";
30
- * import { WasmKeyProvider } from "@tinycloud/node-sdk";
31
- *
32
- * const sessionManager = new SessionManager();
33
- * const keyProvider = new WasmKeyProvider({ sessionManager });
34
- *
35
- * // Create a session key for a sharing link
36
- * const keyId = await keyProvider.createSessionKey("share:abc123");
37
- * const jwk = keyProvider.getJWK(keyId);
38
- * const did = await keyProvider.getDID(keyId);
39
- * ```
40
- */
41
- export declare class WasmKeyProvider implements KeyProvider {
42
- private sessionManager;
43
- /**
44
- * Create a new WasmKeyProvider.
45
- *
46
- * @param config - Configuration with the WASM session manager
47
- */
48
- constructor(config: WasmKeyProviderConfig);
49
- /**
50
- * Generate a new session key with the given name.
51
- *
52
- * This creates a new Ed25519 key pair in the WASM session manager.
53
- * The key can then be used for signing delegations in sharing links.
54
- *
55
- * @param name - A unique name/ID for the key (e.g., "share:timestamp:random")
56
- * @returns The key ID (same as the name provided)
57
- */
58
- createSessionKey(name: string): Promise<string>;
59
- /**
60
- * Get the JWK (JSON Web Key) for a key.
61
- *
62
- * Returns the full JWK including the private key (d parameter),
63
- * which is required for signing and for embedding in sharing links.
64
- *
65
- * @param keyId - The key ID to retrieve
66
- * @returns The JWK object with public and private key components
67
- * @throws Error if the key is not found
68
- */
69
- getJWK(keyId: string): JWK;
70
- /**
71
- * Get the DID (Decentralized Identifier) for a key.
72
- *
73
- * Returns the did:key format DID derived from the key's public key.
74
- * This DID can be used as the delegatee in delegations.
75
- *
76
- * @param keyId - The key ID to retrieve
77
- * @returns The DID in did:key format (e.g., "did:key:z6Mk...")
78
- */
79
- getDID(keyId: string): Promise<string>;
80
- /**
81
- * List all session keys currently held by the provider.
82
- *
83
- * @returns Array of key IDs
84
- */
85
- listKeys(): string[];
86
- /**
87
- * Check if a key exists in the provider.
88
- *
89
- * @param keyId - The key ID to check
90
- * @returns True if the key exists
91
- */
92
- hasKey(keyId: string): boolean;
93
- }
94
- /**
95
- * Create a new WasmKeyProvider instance.
96
- *
97
- * @param sessionManager - The WASM session manager
98
- * @returns A new WasmKeyProvider instance
99
- */
100
- export declare function createWasmKeyProvider(sessionManager: SessionManager): WasmKeyProvider;
101
- //# sourceMappingURL=WasmKeyProvider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"WasmKeyProvider.d.ts","sourceRoot":"","sources":["../../src/keys/WasmKeyProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAEpF;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,eAAgB,YAAW,WAAW;IACjD,OAAO,CAAC,cAAc,CAAiB;IAEvC;;;;OAIG;gBACS,MAAM,EAAE,qBAAqB;IAIzC;;;;;;;;OAQG;IACG,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMrD;;;;;;;;;OASG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG;IAU1B;;;;;;;;OAQG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK5C;;;;OAIG;IACH,QAAQ,IAAI,MAAM,EAAE;IAKpB;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAI/B;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,cAAc,GAAG,eAAe,CAErF"}
@@ -1,113 +0,0 @@
1
- /**
2
- * WasmKeyProvider - KeyProvider implementation using WASM session manager.
3
- *
4
- * This provider wraps the SessionManager from node-sdk-wasm to provide
5
- * cryptographic key operations required by the SharingService.
6
- *
7
- * @packageDocumentation
8
- */
9
- /**
10
- * KeyProvider implementation that wraps the WASM session manager.
11
- *
12
- * This allows the SharingService to create new session keys for sharing links
13
- * using the same cryptographic operations as the main session management.
14
- *
15
- * @example
16
- * ```typescript
17
- * import { SessionManager } from "@tinycloud/node-sdk-wasm";
18
- * import { WasmKeyProvider } from "@tinycloud/node-sdk";
19
- *
20
- * const sessionManager = new SessionManager();
21
- * const keyProvider = new WasmKeyProvider({ sessionManager });
22
- *
23
- * // Create a session key for a sharing link
24
- * const keyId = await keyProvider.createSessionKey("share:abc123");
25
- * const jwk = keyProvider.getJWK(keyId);
26
- * const did = await keyProvider.getDID(keyId);
27
- * ```
28
- */
29
- export class WasmKeyProvider {
30
- /**
31
- * Create a new WasmKeyProvider.
32
- *
33
- * @param config - Configuration with the WASM session manager
34
- */
35
- constructor(config) {
36
- this.sessionManager = config.sessionManager;
37
- }
38
- /**
39
- * Generate a new session key with the given name.
40
- *
41
- * This creates a new Ed25519 key pair in the WASM session manager.
42
- * The key can then be used for signing delegations in sharing links.
43
- *
44
- * @param name - A unique name/ID for the key (e.g., "share:timestamp:random")
45
- * @returns The key ID (same as the name provided)
46
- */
47
- async createSessionKey(name) {
48
- // The WASM session manager's createSessionKey returns the key_id
49
- // and stores the key internally
50
- return this.sessionManager.createSessionKey(name);
51
- }
52
- /**
53
- * Get the JWK (JSON Web Key) for a key.
54
- *
55
- * Returns the full JWK including the private key (d parameter),
56
- * which is required for signing and for embedding in sharing links.
57
- *
58
- * @param keyId - The key ID to retrieve
59
- * @returns The JWK object with public and private key components
60
- * @throws Error if the key is not found
61
- */
62
- getJWK(keyId) {
63
- // The WASM session manager returns the JWK as a JSON string
64
- const jwkJson = this.sessionManager.jwk(keyId);
65
- if (!jwkJson) {
66
- throw new Error(`Key not found: ${keyId}`);
67
- }
68
- // Parse the JSON string to get the JWK object
69
- return JSON.parse(jwkJson);
70
- }
71
- /**
72
- * Get the DID (Decentralized Identifier) for a key.
73
- *
74
- * Returns the did:key format DID derived from the key's public key.
75
- * This DID can be used as the delegatee in delegations.
76
- *
77
- * @param keyId - The key ID to retrieve
78
- * @returns The DID in did:key format (e.g., "did:key:z6Mk...")
79
- */
80
- async getDID(keyId) {
81
- // The WASM session manager has a synchronous getDID method
82
- return this.sessionManager.getDID(keyId);
83
- }
84
- /**
85
- * List all session keys currently held by the provider.
86
- *
87
- * @returns Array of key IDs
88
- */
89
- listKeys() {
90
- const keys = this.sessionManager.listSessionKeys();
91
- return Array.isArray(keys) ? keys : [];
92
- }
93
- /**
94
- * Check if a key exists in the provider.
95
- *
96
- * @param keyId - The key ID to check
97
- * @returns True if the key exists
98
- */
99
- hasKey(keyId) {
100
- const jwk = this.sessionManager.jwk(keyId);
101
- return jwk !== undefined;
102
- }
103
- }
104
- /**
105
- * Create a new WasmKeyProvider instance.
106
- *
107
- * @param sessionManager - The WASM session manager
108
- * @returns A new WasmKeyProvider instance
109
- */
110
- export function createWasmKeyProvider(sessionManager) {
111
- return new WasmKeyProvider({ sessionManager });
112
- }
113
- //# sourceMappingURL=WasmKeyProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"WasmKeyProvider.js","sourceRoot":"","sources":["../../src/keys/WasmKeyProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgBH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,eAAe;IAG1B;;;;OAIG;IACH,YAAY,MAA6B;QACvC,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;IAC9C,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,gBAAgB,CAAC,IAAY;QACjC,iEAAiE;QACjE,gCAAgC;QAChC,OAAO,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,KAAa;QAClB,4DAA4D;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,8CAA8C;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAQ,CAAC;IACpC,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,MAAM,CAAC,KAAa;QACxB,2DAA2D;QAC3D,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACN,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC;QACnD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAa;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3C,OAAO,GAAG,KAAK,SAAS,CAAC;IAC3B,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,cAA8B;IAClE,OAAO,IAAI,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC;AACjD,CAAC"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Key management module for node-sdk.
3
- *
4
- * @packageDocumentation
5
- */
6
- export { WasmKeyProvider, WasmKeyProviderConfig, createWasmKeyProvider } from "./WasmKeyProvider";
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Key management module for node-sdk.
3
- *
4
- * @packageDocumentation
5
- */
6
- export { WasmKeyProvider, createWasmKeyProvider } from "./WasmKeyProvider";
7
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAyB,qBAAqB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,47 +0,0 @@
1
- import { ISigner, Bytes } from "@tinycloud/sdk-core";
2
- /**
3
- * Private key signer for Node.js environments.
4
- *
5
- * Uses the node-sdk-wasm package for Ethereum signing operations.
6
- * The private key should be a hex string (with or without 0x prefix).
7
- *
8
- * @example
9
- * ```typescript
10
- * const signer = new PrivateKeySigner(process.env.PRIVATE_KEY);
11
- * const address = await signer.getAddress();
12
- * const signature = await signer.signMessage("Hello, world!");
13
- * ```
14
- */
15
- export declare class PrivateKeySigner implements ISigner {
16
- private readonly privateKeyHex;
17
- private readonly chainId;
18
- private cachedAddress?;
19
- /**
20
- * Create a new PrivateKeySigner.
21
- *
22
- * @param privateKey - Hex-encoded private key (with or without 0x prefix)
23
- * @param chainId - Chain ID for signing (default: 1 for mainnet)
24
- */
25
- constructor(privateKey: string, chainId?: number);
26
- /**
27
- * Get the Ethereum address for this signer.
28
- */
29
- getAddress(): Promise<string>;
30
- /**
31
- * Derive Ethereum address from private key.
32
- * Uses secp256k1 public key derivation via ethers.js.
33
- */
34
- private deriveAddress;
35
- /**
36
- * Get the chain ID for this signer.
37
- */
38
- getChainId(): Promise<number>;
39
- /**
40
- * Sign a message.
41
- *
42
- * @param message - The message to sign (string or bytes)
43
- * @returns The signature as a hex string
44
- */
45
- signMessage(message: Bytes | string): Promise<string>;
46
- }
47
- //# sourceMappingURL=PrivateKeySigner.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PrivateKeySigner.d.ts","sourceRoot":"","sources":["../../src/signers/PrivateKeySigner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAMrD;;;;;;;;;;;;GAYG;AACH,qBAAa,gBAAiB,YAAW,OAAO;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,aAAa,CAAC,CAAS;IAE/B;;;;;OAKG;gBACS,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,MAAU;IAanD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IASnC;;;OAGG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAInC;;;;;OAKG;IACG,WAAW,CAAC,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAa5D"}
@@ -1,89 +0,0 @@
1
- import { signEthereumMessage, ensureEip55, } from "@tinycloud/node-sdk-wasm";
2
- /**
3
- * Private key signer for Node.js environments.
4
- *
5
- * Uses the node-sdk-wasm package for Ethereum signing operations.
6
- * The private key should be a hex string (with or without 0x prefix).
7
- *
8
- * @example
9
- * ```typescript
10
- * const signer = new PrivateKeySigner(process.env.PRIVATE_KEY);
11
- * const address = await signer.getAddress();
12
- * const signature = await signer.signMessage("Hello, world!");
13
- * ```
14
- */
15
- export class PrivateKeySigner {
16
- /**
17
- * Create a new PrivateKeySigner.
18
- *
19
- * @param privateKey - Hex-encoded private key (with or without 0x prefix)
20
- * @param chainId - Chain ID for signing (default: 1 for mainnet)
21
- */
22
- constructor(privateKey, chainId = 1) {
23
- // Normalize private key format (remove 0x prefix)
24
- this.privateKeyHex = privateKey.startsWith("0x")
25
- ? privateKey.slice(2)
26
- : privateKey;
27
- this.chainId = chainId;
28
- // Validate private key length
29
- if (this.privateKeyHex.length !== 64) {
30
- throw new Error("Invalid private key: must be 32 bytes (64 hex chars)");
31
- }
32
- }
33
- /**
34
- * Get the Ethereum address for this signer.
35
- */
36
- async getAddress() {
37
- if (this.cachedAddress) {
38
- return this.cachedAddress;
39
- }
40
- this.cachedAddress = this.deriveAddress();
41
- return this.cachedAddress;
42
- }
43
- /**
44
- * Derive Ethereum address from private key.
45
- * Uses secp256k1 public key derivation via ethers.js.
46
- */
47
- deriveAddress() {
48
- try {
49
- // Derive public key from private key using secp256k1
50
- const { keccak256 } = require("ethers/lib/utils");
51
- const { SigningKey } = require("ethers/lib/utils");
52
- const signingKey = new SigningKey("0x" + this.privateKeyHex);
53
- const publicKey = signingKey.publicKey;
54
- // Remove '0x04' prefix (uncompressed point indicator)
55
- const pubKeyWithoutPrefix = publicKey.slice(4);
56
- const hash = keccak256("0x" + pubKeyWithoutPrefix);
57
- // Take last 20 bytes
58
- const address = "0x" + hash.slice(-40);
59
- return ensureEip55(address);
60
- }
61
- catch {
62
- // Fallback: use dummy address for testing
63
- return "0x" + this.privateKeyHex.slice(0, 40);
64
- }
65
- }
66
- /**
67
- * Get the chain ID for this signer.
68
- */
69
- async getChainId() {
70
- return this.chainId;
71
- }
72
- /**
73
- * Sign a message.
74
- *
75
- * @param message - The message to sign (string or bytes)
76
- * @returns The signature as a hex string
77
- */
78
- async signMessage(message) {
79
- const messageStr = typeof message === "string"
80
- ? message
81
- : Buffer.from(message).toString("utf-8");
82
- // Use WASM to sign with Ethereum personal_sign format
83
- // WASM now accepts hex-encoded private key directly
84
- const signature = signEthereumMessage(messageStr, this.privateKeyHex);
85
- // Ensure signature has 0x prefix
86
- return signature.startsWith("0x") ? signature : "0x" + signature;
87
- }
88
- }
89
- //# sourceMappingURL=PrivateKeySigner.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PrivateKeySigner.js","sourceRoot":"","sources":["../../src/signers/PrivateKeySigner.ts"],"names":[],"mappings":"AACA,OAAO,EACL,mBAAmB,EACnB,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,gBAAgB;IAK3B;;;;;OAKG;IACH,YAAY,UAAkB,EAAE,UAAkB,CAAC;QACjD,kDAAkD;QAClD,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC;YAC9C,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;YACrB,CAAC,CAAC,UAAU,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,8BAA8B;QAC9B,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACK,aAAa;QACnB,IAAI,CAAC;YACH,qDAAqD;YACrD,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;YAClD,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;YAEnD,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;YAC7D,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;YACvC,sDAAsD;YACtD,MAAM,mBAAmB,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,GAAG,mBAAmB,CAAC,CAAC;YACnD,qBAAqB;YACrB,MAAM,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YACvC,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,0CAA0C;YAC1C,OAAO,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CAAC,OAAuB;QACvC,MAAM,UAAU,GACd,OAAO,OAAO,KAAK,QAAQ;YACzB,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAA4B,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAElE,sDAAsD;QACtD,oDAAoD;QACpD,MAAM,SAAS,GAAG,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAEtE,iCAAiC;QACjC,OAAO,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC;IACnE,CAAC;CACF"}
@@ -1,59 +0,0 @@
1
- import { ISessionStorage, PersistedSessionData } from "@tinycloud/sdk-core";
2
- /**
3
- * File-based session storage for Node.js.
4
- *
5
- * Sessions are persisted to the file system and survive process restarts.
6
- * Suitable for:
7
- * - CLI applications
8
- * - Long-running server processes
9
- * - Development environments
10
- *
11
- * @example
12
- * ```typescript
13
- * const storage = new FileSessionStorage("/tmp/tinycloud-sessions");
14
- * await storage.save("0x123...", sessionData);
15
- * // Session persists across process restarts
16
- * ```
17
- */
18
- export declare class FileSessionStorage implements ISessionStorage {
19
- private readonly baseDir;
20
- /**
21
- * Create a new FileSessionStorage.
22
- *
23
- * @param baseDir - Directory to store session files (default: ~/.tinycloud/sessions)
24
- */
25
- constructor(baseDir?: string);
26
- /**
27
- * Get the default session storage directory.
28
- */
29
- private getDefaultDir;
30
- /**
31
- * Ensure the storage directory exists.
32
- */
33
- private ensureDirectoryExists;
34
- /**
35
- * Get the file path for an address.
36
- */
37
- private getFilePath;
38
- /**
39
- * Save a session for an address.
40
- */
41
- save(address: string, session: PersistedSessionData): Promise<void>;
42
- /**
43
- * Load a session for an address.
44
- */
45
- load(address: string): Promise<PersistedSessionData | null>;
46
- /**
47
- * Clear a session for an address.
48
- */
49
- clear(address: string): Promise<void>;
50
- /**
51
- * Check if a session exists for an address.
52
- */
53
- exists(address: string): boolean;
54
- /**
55
- * Check if file system storage is available.
56
- */
57
- isAvailable(): boolean;
58
- }
59
- //# sourceMappingURL=FileSessionStorage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FileSessionStorage.d.ts","sourceRoot":"","sources":["../../src/storage/FileSessionStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAgC,MAAM,qBAAqB,CAAC;AAI1G;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC;;;;OAIG;gBACS,OAAO,CAAC,EAAE,MAAM;IAK5B;;OAEG;IACH,OAAO,CAAC,aAAa;IAKrB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAM7B;;OAEG;IACH,OAAO,CAAC,WAAW;IAOnB;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzE;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IA0CjE;;OAEG;IACG,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3C;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAwBhC;;OAEG;IACH,WAAW,IAAI,OAAO;CAQvB"}
@@ -1,148 +0,0 @@
1
- import { validatePersistedSessionData } from "@tinycloud/sdk-core";
2
- import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from "fs";
3
- import { join } from "path";
4
- /**
5
- * File-based session storage for Node.js.
6
- *
7
- * Sessions are persisted to the file system and survive process restarts.
8
- * Suitable for:
9
- * - CLI applications
10
- * - Long-running server processes
11
- * - Development environments
12
- *
13
- * @example
14
- * ```typescript
15
- * const storage = new FileSessionStorage("/tmp/tinycloud-sessions");
16
- * await storage.save("0x123...", sessionData);
17
- * // Session persists across process restarts
18
- * ```
19
- */
20
- export class FileSessionStorage {
21
- /**
22
- * Create a new FileSessionStorage.
23
- *
24
- * @param baseDir - Directory to store session files (default: ~/.tinycloud/sessions)
25
- */
26
- constructor(baseDir) {
27
- this.baseDir = baseDir || this.getDefaultDir();
28
- this.ensureDirectoryExists();
29
- }
30
- /**
31
- * Get the default session storage directory.
32
- */
33
- getDefaultDir() {
34
- const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
35
- return join(home, ".tinycloud", "sessions");
36
- }
37
- /**
38
- * Ensure the storage directory exists.
39
- */
40
- ensureDirectoryExists() {
41
- if (!existsSync(this.baseDir)) {
42
- mkdirSync(this.baseDir, { recursive: true });
43
- }
44
- }
45
- /**
46
- * Get the file path for an address.
47
- */
48
- getFilePath(address) {
49
- const normalizedAddress = address.toLowerCase();
50
- // Use a hash of the address to avoid filesystem issues
51
- const filename = `${normalizedAddress.replace("0x", "")}.json`;
52
- return join(this.baseDir, filename);
53
- }
54
- /**
55
- * Save a session for an address.
56
- */
57
- async save(address, session) {
58
- const filePath = this.getFilePath(address);
59
- const data = JSON.stringify(session, null, 2);
60
- writeFileSync(filePath, data, "utf-8");
61
- }
62
- /**
63
- * Load a session for an address.
64
- */
65
- async load(address) {
66
- const filePath = this.getFilePath(address);
67
- if (!existsSync(filePath)) {
68
- return null;
69
- }
70
- try {
71
- const data = readFileSync(filePath, "utf-8");
72
- const parsed = JSON.parse(data);
73
- // Validate loaded data against schema
74
- const validation = validatePersistedSessionData(parsed);
75
- if (!validation.ok) {
76
- console.warn(`Invalid session data for ${address}:`, validation.error.message);
77
- // Clean up invalid session
78
- unlinkSync(filePath);
79
- return null;
80
- }
81
- const session = validation.data;
82
- // Check if session is expired
83
- const expiresAt = new Date(session.expiresAt);
84
- if (expiresAt < new Date()) {
85
- // Clean up expired session
86
- unlinkSync(filePath);
87
- return null;
88
- }
89
- return session;
90
- }
91
- catch (error) {
92
- // Invalid JSON or read error - remove the file
93
- try {
94
- unlinkSync(filePath);
95
- }
96
- catch {
97
- // Ignore cleanup errors
98
- }
99
- return null;
100
- }
101
- }
102
- /**
103
- * Clear a session for an address.
104
- */
105
- async clear(address) {
106
- const filePath = this.getFilePath(address);
107
- if (existsSync(filePath)) {
108
- unlinkSync(filePath);
109
- }
110
- }
111
- /**
112
- * Check if a session exists for an address.
113
- */
114
- exists(address) {
115
- const filePath = this.getFilePath(address);
116
- if (!existsSync(filePath)) {
117
- return false;
118
- }
119
- try {
120
- const data = readFileSync(filePath, "utf-8");
121
- const session = JSON.parse(data);
122
- // Check if session is expired
123
- const expiresAt = new Date(session.expiresAt);
124
- if (expiresAt < new Date()) {
125
- // Clean up expired session
126
- unlinkSync(filePath);
127
- return false;
128
- }
129
- return true;
130
- }
131
- catch {
132
- return false;
133
- }
134
- }
135
- /**
136
- * Check if file system storage is available.
137
- */
138
- isAvailable() {
139
- try {
140
- this.ensureDirectoryExists();
141
- return existsSync(this.baseDir);
142
- }
143
- catch {
144
- return false;
145
- }
146
- }
147
- }
148
- //# sourceMappingURL=FileSessionStorage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FileSessionStorage.js","sourceRoot":"","sources":["../../src/storage/FileSessionStorage.ts"],"names":[],"mappings":"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"}