@parity/product-sdk 0.6.0 → 0.7.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.
@@ -1,8 +1,8 @@
1
1
  export * from '@parity/product-sdk-address';
2
- import '@parity/product-sdk-bulletin';
2
+ import '@parity/product-sdk-cloud-storage';
3
3
  import '@parity/product-sdk-chain-client';
4
4
  import '@parity/product-sdk-contracts';
5
5
  import '@parity/product-sdk-crypto';
6
6
  import '@parity/product-sdk-host';
7
- import '@parity/product-sdk-storage';
7
+ import '@parity/product-sdk-local-storage';
8
8
  import '@parity/product-sdk-signer';
@@ -1,7 +1,7 @@
1
1
  import { createLogger, configure } from '@parity/product-sdk-logger';
2
- import { createKvStore } from '@parity/product-sdk-storage';
2
+ import { createLocalKvStore } from '@parity/product-sdk-local-storage';
3
3
  import { SignerManager } from '@parity/product-sdk-signer';
4
- import { BulletinClient, createLazySigner, calculateCid } from '@parity/product-sdk-bulletin';
4
+ import { CloudStorageClient, createLazySigner, calculateCid } from '@parity/product-sdk-cloud-storage';
5
5
  import { destroyAll, isConnected, createChainClient, getClient } from '@parity/product-sdk-chain-client';
6
6
 
7
7
  // src/core/createApp.ts
@@ -11,27 +11,29 @@ async function createApp(config) {
11
11
  configure({ level: config.logLevel });
12
12
  }
13
13
  log.info("Creating Product SDK app", { name: config.name });
14
- const kvStore = await createKvStore({ prefix: config.name });
14
+ const localKvStore = await createLocalKvStore({ prefix: config.name });
15
15
  const signerManager = new SignerManager({
16
16
  dappName: config.name
17
17
  });
18
- const bulletinEnabled = config.bulletin !== false;
19
- const bulletinEnvironment = typeof config.bulletin === "object" ? config.bulletin.environment : "paseo";
20
- const bulletinClient = bulletinEnabled ? await BulletinClient.create({
21
- environment: bulletinEnvironment,
18
+ const cloudStorageEnabled = config.cloudStorage !== false;
19
+ const cloudStorageEnvironment = typeof config.cloudStorage === "object" ? config.cloudStorage.environment : "paseo";
20
+ const cloudStorageClient = cloudStorageEnabled ? await CloudStorageClient.create({
21
+ environment: cloudStorageEnvironment,
22
22
  signer: createLazySigner(() => signerManager.getSigner())
23
23
  }) : null;
24
- if (bulletinEnabled) {
25
- log.debug("Bulletin client initialized", { environment: bulletinEnvironment });
24
+ if (cloudStorageEnabled) {
25
+ log.debug("Cloud Storage client (Bulletin) initialized", {
26
+ environment: cloudStorageEnvironment
27
+ });
26
28
  } else {
27
- log.debug("Bulletin client disabled");
29
+ log.debug("Cloud Storage client disabled");
28
30
  }
29
- const storageApi = {
30
- get: (key) => kvStore.get(key),
31
- set: (key, value) => kvStore.set(key, value),
32
- getJSON: (key) => kvStore.getJSON(key),
33
- setJSON: (key, value) => kvStore.setJSON(key, value),
34
- remove: (key) => kvStore.remove(key),
31
+ const localStorageApi = {
32
+ get: (key) => localKvStore.get(key),
33
+ set: (key, value) => localKvStore.set(key, value),
34
+ getJSON: (key) => localKvStore.getJSON(key),
35
+ setJSON: (key, value) => localKvStore.setJSON(key, value),
36
+ remove: (key) => localKvStore.remove(key),
35
37
  clear: async () => {
36
38
  log.debug("clear() is not supported in container storage mode");
37
39
  }
@@ -62,18 +64,18 @@ async function createApp(config) {
62
64
  destroyAll();
63
65
  }
64
66
  };
65
- const bulletinApi = bulletinClient ? {
67
+ const cloudStorageApi = cloudStorageClient ? {
66
68
  upload: async (data) => {
67
69
  const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
68
- const result = await bulletinClient.store(bytes).withManifest(true).send();
70
+ const result = await cloudStorageClient.store(bytes).withManifest(true).send();
69
71
  if (!result.cid) {
70
72
  throw new Error(
71
- "Bulletin upload returned no CID despite .withManifest(true). Upstream contract may have shifted \u2014 file an issue."
73
+ "Cloud storage upload returned no CID despite .withManifest(true). Upstream contract may have shifted \u2014 file an issue."
72
74
  );
73
75
  }
74
76
  return result.cid.toString();
75
77
  },
76
- fetch: (cid) => bulletinClient.fetchBytes(cid),
78
+ fetch: (cid) => cloudStorageClient.fetchBytes(cid),
77
79
  computeCid: async (data) => {
78
80
  const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
79
81
  const cid = await calculateCid(bytes);
@@ -82,13 +84,13 @@ async function createApp(config) {
82
84
  } : null;
83
85
  log.info("Product SDK app created", {
84
86
  name: config.name,
85
- bulletin: bulletinEnabled ? bulletinEnvironment : "disabled"
87
+ cloudStorage: cloudStorageEnabled ? cloudStorageEnvironment : "disabled"
86
88
  });
87
89
  return {
88
90
  wallet: walletApi,
89
- storage: storageApi,
91
+ localStorage: localStorageApi,
90
92
  chain: chainApi,
91
- bulletin: bulletinApi,
93
+ cloudStorage: cloudStorageApi,
92
94
  getAppInfo: () => ({ ...config })
93
95
  };
94
96
  }
@@ -177,5 +179,5 @@ function createWalletApi(signerManager) {
177
179
  }
178
180
 
179
181
  export { createApp };
180
- //# sourceMappingURL=chunk-6W3TCR3W.js.map
181
- //# sourceMappingURL=chunk-6W3TCR3W.js.map
182
+ //# sourceMappingURL=chunk-4U2FP26I.js.map
183
+ //# sourceMappingURL=chunk-4U2FP26I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/createApp.ts"],"names":[],"mappings":"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","file":"chunk-4U2FP26I.js","sourcesContent":["/**\n * createApp - Main entry point for the Product SDK\n *\n * Creates an App instance with wallet, storage, chain, and cloud storage APIs.\n */\n\nimport type { ChainDefinition } from \"polkadot-api\";\nimport type {\n App,\n AppConfig,\n WalletApi,\n ChainApi,\n Account,\n CloudStorageApi,\n LocalStorageApi,\n} from \"./types.js\";\nimport { configure, createLogger } from \"@parity/product-sdk-logger\";\nimport { createLocalKvStore } from \"@parity/product-sdk-local-storage\";\nimport { SignerManager } from \"@parity/product-sdk-signer\";\nimport {\n CloudStorageClient,\n calculateCid,\n createLazySigner,\n} from \"@parity/product-sdk-cloud-storage\";\nimport {\n createChainClient,\n getClient,\n isConnected,\n destroyAll,\n} from \"@parity/product-sdk-chain-client\";\n\nconst log = createLogger(\"app\");\n\n/**\n * Create a new Product SDK app instance\n *\n * @param config - Application configuration\n * @returns App instance with all APIs\n *\n * @example\n * ```ts\n * import { createApp } from '@parity/product-sdk';\n *\n * // Default: cloud storage enabled with paseo environment\n * const app = await createApp({\n * name: 'my-app',\n * logLevel: 'info',\n * });\n *\n * // Custom cloud storage environment\n * const prodApp = await createApp({\n * name: 'my-app',\n * cloudStorage: { environment: 'polkadot' },\n * });\n *\n * // Disable cloud storage entirely\n * const noCloudStorageApp = await createApp({\n * name: 'my-app',\n * cloudStorage: false,\n * });\n *\n * // Connect wallet\n * const { accounts } = await app.wallet.connect();\n *\n * // Use storage\n * await app.localStorage.set('key', 'value');\n *\n * // Use cloud storage (check for null if it might be disabled)\n * if (app.cloudStorage) {\n * const cid = await app.cloudStorage.upload('hello world');\n * }\n * ```\n */\nexport async function createApp(config: AppConfig): Promise<App> {\n // Set log level if specified\n if (config.logLevel) {\n configure({ level: config.logLevel });\n }\n\n log.info(\"Creating Product SDK app\", { name: config.name });\n\n // Initialize storage (container-only - will throw if not in container)\n const localKvStore = await createLocalKvStore({ prefix: config.name });\n\n // Initialize signer manager\n const signerManager = new SignerManager({\n dappName: config.name,\n });\n\n // Initialize cloud storage client (configurable, defaults to paseo).\n //\n // The signer is wrapped lazily so the cloud storage client can be built before\n // an account is selected. Uploads will throw a clear error if no signer\n // is available at submission time. Reads (fetch / fetchJson) don't need\n // a signer and work regardless.\n const cloudStorageEnabled = config.cloudStorage !== false;\n const cloudStorageEnvironment =\n typeof config.cloudStorage === \"object\" ? config.cloudStorage.environment : \"paseo\";\n const cloudStorageClient = cloudStorageEnabled\n ? await CloudStorageClient.create({\n environment: cloudStorageEnvironment,\n signer: createLazySigner(() => signerManager.getSigner()),\n })\n : null;\n\n if (cloudStorageEnabled) {\n log.debug(\"Cloud Storage client (Bulletin) initialized\", {\n environment: cloudStorageEnvironment,\n });\n } else {\n log.debug(\"Cloud Storage client disabled\");\n }\n\n // Create storage API adapter\n const localStorageApi: LocalStorageApi = {\n get: (key) => localKvStore.get(key),\n set: (key, value) => localKvStore.set(key, value),\n getJSON: <T>(key: string) => localKvStore.getJSON<T>(key),\n setJSON: <T>(key: string, value: T) => localKvStore.setJSON(key, value),\n remove: (key) => localKvStore.remove(key),\n clear: async () => {\n // LocalKvStore doesn't have clear - this is a no-op\n log.debug(\"clear() is not supported in container storage mode\");\n },\n };\n\n // Create wallet API adapter\n const walletApi = createWalletApi(signerManager);\n\n // Create chain API\n const chainApi: ChainApi = {\n getClient(descriptor) {\n log.debug(\"getClient called\", { genesis: descriptor.genesis });\n const client = getClient(descriptor);\n return client.getTypedApi(descriptor);\n },\n\n getRawClient(descriptor) {\n log.debug(\"getRawClient called\", { genesis: descriptor.genesis });\n return getClient(descriptor);\n },\n\n async connect<T extends Record<string, ChainDefinition>>(chains: T) {\n log.debug(\"connect called\", { chains: Object.keys(chains) });\n // Build empty rpcs object (required by API but unused - host routes connections)\n const rpcs = Object.fromEntries(\n Object.keys(chains).map((k) => [k, [] as readonly string[]]),\n ) as { [K in keyof T]: readonly string[] };\n return createChainClient({ chains, rpcs });\n },\n\n isConnected(descriptor) {\n return isConnected(descriptor);\n },\n\n destroyAll() {\n log.debug(\"destroyAll called\");\n destroyAll();\n },\n };\n\n // Create Cloud Storage API adapter (null if disabled)\n const cloudStorageApi: CloudStorageApi | null = cloudStorageClient\n ? {\n upload: async (data) => {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n // Explicitly request a DAG-PB manifest so chunked uploads always\n // resolve to a single root CID. Without this, AsyncBulletinClient\n // can return `result.cid: undefined` for chunked-without-manifest\n // uploads — but CloudStorageApi.upload promises a string return, and\n // app consumers expect a CID they can hand to `fetch(cid)`. Keep\n // the defensive null-check below as belt-and-braces in case the\n // upstream contract shifts.\n const result = await cloudStorageClient.store(bytes).withManifest(true).send();\n if (!result.cid) {\n throw new Error(\n \"Cloud storage upload returned no CID despite .withManifest(true). Upstream contract may have shifted — file an issue.\",\n );\n }\n return result.cid.toString();\n },\n fetch: (cid) => cloudStorageClient.fetchBytes(cid),\n computeCid: async (data) => {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n const cid = await calculateCid(bytes);\n return cid.toString();\n },\n }\n : null;\n\n log.info(\"Product SDK app created\", {\n name: config.name,\n cloudStorage: cloudStorageEnabled ? cloudStorageEnvironment : \"disabled\",\n });\n\n return {\n wallet: walletApi,\n localStorage: localStorageApi,\n chain: chainApi,\n cloudStorage: cloudStorageApi,\n getAppInfo: () => ({ ...config }),\n };\n}\n\n/**\n * Create wallet API adapter using SignerManager from leaf package\n */\nfunction createWalletApi(signerManager: SignerManager): WalletApi {\n // Track account change subscribers\n const accountChangeSubscribers = new Set<(account: Account | null) => void>();\n\n // Subscribe to signer manager state changes\n signerManager.subscribe((state) => {\n const account = state.selectedAccount\n ? {\n address: state.selectedAccount.address,\n name: state.selectedAccount.name ?? undefined,\n source: state.selectedAccount.source,\n }\n : null;\n for (const callback of accountChangeSubscribers) {\n try {\n callback(account);\n } catch (e) {\n log.warn(\"Account change callback threw\", { error: e });\n }\n }\n });\n\n return {\n async connect(): Promise<{ accounts: Account[] }> {\n const result = await signerManager.connect();\n if (!result.ok) {\n throw new Error(result.error.message);\n }\n return {\n accounts: result.value.map((a) => ({\n address: a.address,\n name: a.name ?? undefined,\n source: a.source,\n })),\n };\n },\n\n async disconnect(): Promise<void> {\n signerManager.disconnect();\n },\n\n getAccounts(): Account[] {\n return signerManager.getState().accounts.map((a) => ({\n address: a.address,\n name: a.name ?? undefined,\n source: a.source,\n }));\n },\n\n getSelectedAccount(): Account | null {\n const selected = signerManager.getState().selectedAccount;\n if (!selected) return null;\n return {\n address: selected.address,\n name: selected.name ?? undefined,\n source: selected.source,\n };\n },\n\n selectAccount(address: string): void {\n signerManager.selectAccount(address);\n },\n\n async signMessage(message: string | Uint8Array): Promise<Uint8Array> {\n const bytes = typeof message === \"string\" ? new TextEncoder().encode(message) : message;\n const result = await signerManager.signRaw(bytes);\n if (!result.ok) {\n throw new Error(result.error.message);\n }\n return result.value;\n },\n\n onAccountChange(callback: (account: Account | null) => void): () => void {\n accountChangeSubscribers.add(callback);\n return () => accountChangeSubscribers.delete(callback);\n },\n\n getProductAccount(): Account | null {\n // Product accounts require async call - this sync API can't support it properly\n // Users should use SignerManager.getProductAccount() directly\n log.warn(\n \"getProductAccount() is deprecated - use SignerManager.getProductAccount() directly\",\n );\n return null;\n },\n\n getAnonymousAlias(): string | null {\n // Anonymous aliases require async call - this sync API can't support it properly\n // Users should use SignerManager.getProductAccountAlias() directly\n log.warn(\n \"getAnonymousAlias() is deprecated - use SignerManager.getProductAccountAlias() directly\",\n );\n return null;\n },\n\n async createProof(_message: Uint8Array): Promise<Uint8Array> {\n // Ring VRF proofs require SignerManager.createRingVRFProof() directly\n throw new Error(\n \"createProof() is not implemented in the App API. \" +\n \"Use SignerManager.createRingVRFProof() directly.\",\n );\n },\n };\n}\n"]}
@@ -0,0 +1 @@
1
+ export * from '@parity/product-sdk-cloud-storage';
@@ -0,0 +1,3 @@
1
+ export * from '@parity/product-sdk-cloud-storage';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -1,9 +1,9 @@
1
1
  export { createApp } from '../index.js';
2
2
  export { LogEntry, LogHandler, LogLevel, Logger, LoggerConfig, configure, createLogger } from '@parity/product-sdk-logger';
3
- export { a as Account, A as App, b as AppConfig, B as BulletinApi, c as BulletinConfig, C as ChainApi, S as StorageApi, W as WalletApi } from '../types-DVpAr2JN.js';
3
+ export { a as Account, A as App, b as AppConfig, C as ChainApi, c as CloudStorageApi, d as CloudStorageConfig, L as LocalStorageApi, W as WalletApi } from '../types-AjDV1BTd.js';
4
4
  export { ChainClient } from '@parity/product-sdk-chain-client';
5
5
  export { ChainDefinition, PolkadotClient, TypedApi } from 'polkadot-api';
6
6
  import '@parity/product-sdk-host';
7
7
  import '@parity/product-sdk-signer';
8
- import '@parity/product-sdk-storage';
9
- import '@parity/product-sdk-bulletin';
8
+ import '@parity/product-sdk-local-storage';
9
+ import '@parity/product-sdk-cloud-storage';
@@ -1,4 +1,4 @@
1
1
  export { configure, createLogger } from '../chunk-XSKBA5SR.js';
2
- export { createApp } from '../chunk-6W3TCR3W.js';
2
+ export { createApp } from '../chunk-4U2FP26I.js';
3
3
  //# sourceMappingURL=index.js.map
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  export { LogEntry, LogHandler, LogLevel, Logger, LoggerConfig, configure, createLogger } from '@parity/product-sdk-logger';
2
- import { b as AppConfig, A as App } from './types-DVpAr2JN.js';
3
- export { a as Account, B as BulletinApi, C as ChainApi, S as StorageApi, W as WalletApi } from './types-DVpAr2JN.js';
2
+ import { b as AppConfig, A as App } from './types-AjDV1BTd.js';
3
+ export { a as Account, C as ChainApi, c as CloudStorageApi, L as LocalStorageApi, W as WalletApi } from './types-AjDV1BTd.js';
4
4
  export { isInsideContainer, isInsideContainerSync } from '@parity/product-sdk-host';
5
5
  export { ChainClient, createChainClient } from '@parity/product-sdk-chain-client';
6
6
  export { SignerManager } from '@parity/product-sdk-signer';
7
- export { createKvStore } from '@parity/product-sdk-storage';
8
- export { BulletinClient, calculateCid } from '@parity/product-sdk-bulletin';
7
+ export { createLocalKvStore } from '@parity/product-sdk-local-storage';
8
+ export { CloudStorageClient, calculateCid } from '@parity/product-sdk-cloud-storage';
9
9
  export { ChainDefinition, PolkadotClient, TypedApi } from 'polkadot-api';
10
10
 
11
11
  /**
12
12
  * createApp - Main entry point for the Product SDK
13
13
  *
14
- * Creates an App instance with wallet, storage, chain, and bulletin APIs.
14
+ * Creates an App instance with wallet, storage, chain, and cloud storage APIs.
15
15
  */
16
16
 
17
17
  /**
@@ -24,33 +24,33 @@ export { ChainDefinition, PolkadotClient, TypedApi } from 'polkadot-api';
24
24
  * ```ts
25
25
  * import { createApp } from '@parity/product-sdk';
26
26
  *
27
- * // Default: bulletin enabled with paseo environment
27
+ * // Default: cloud storage enabled with paseo environment
28
28
  * const app = await createApp({
29
29
  * name: 'my-app',
30
30
  * logLevel: 'info',
31
31
  * });
32
32
  *
33
- * // Custom bulletin environment
33
+ * // Custom cloud storage environment
34
34
  * const prodApp = await createApp({
35
35
  * name: 'my-app',
36
- * bulletin: { environment: 'polkadot' },
36
+ * cloudStorage: { environment: 'polkadot' },
37
37
  * });
38
38
  *
39
- * // Disable bulletin entirely
40
- * const noBulletinApp = await createApp({
39
+ * // Disable cloud storage entirely
40
+ * const noCloudStorageApp = await createApp({
41
41
  * name: 'my-app',
42
- * bulletin: false,
42
+ * cloudStorage: false,
43
43
  * });
44
44
  *
45
45
  * // Connect wallet
46
46
  * const { accounts } = await app.wallet.connect();
47
47
  *
48
48
  * // Use storage
49
- * await app.storage.set('key', 'value');
49
+ * await app.localStorage.set('key', 'value');
50
50
  *
51
- * // Use bulletin (check for null if it might be disabled)
52
- * if (app.bulletin) {
53
- * const cid = await app.bulletin.upload('hello world');
51
+ * // Use cloud storage (check for null if it might be disabled)
52
+ * if (app.cloudStorage) {
53
+ * const cid = await app.cloudStorage.upload('hello world');
54
54
  * }
55
55
  * ```
56
56
  */
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  export { configure, createLogger } from './chunk-XSKBA5SR.js';
2
- export { createApp } from './chunk-6W3TCR3W.js';
2
+ export { createApp } from './chunk-4U2FP26I.js';
3
3
  export { isInsideContainer, isInsideContainerSync } from '@parity/product-sdk-host';
4
4
  export { createChainClient } from '@parity/product-sdk-chain-client';
5
5
  export { SignerManager } from '@parity/product-sdk-signer';
6
- export { createKvStore } from '@parity/product-sdk-storage';
7
- export { BulletinClient, calculateCid } from '@parity/product-sdk-bulletin';
6
+ export { createLocalKvStore } from '@parity/product-sdk-local-storage';
7
+ export { CloudStorageClient, calculateCid } from '@parity/product-sdk-cloud-storage';
8
8
  //# sourceMappingURL=index.js.map
9
9
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ export * from '@parity/product-sdk-local-storage';
@@ -0,0 +1,3 @@
1
+ export * from '@parity/product-sdk-local-storage';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -2,9 +2,9 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode } from 'react';
4
4
  import { LogLevel } from '@parity/product-sdk-logger';
5
- import { A as App, a as Account } from '../types-DVpAr2JN.js';
5
+ import { A as App, a as Account } from '../types-AjDV1BTd.js';
6
6
  import { ChainDefinition, TypedApi } from 'polkadot-api';
7
- import '@parity/product-sdk-bulletin';
7
+ import '@parity/product-sdk-cloud-storage';
8
8
  import '@parity/product-sdk-chain-client';
9
9
 
10
10
  /** Props for ProductSDKProvider */
@@ -47,7 +47,7 @@ declare const ProductSDKContext: react.Context<App | null>;
47
47
  * ```tsx
48
48
  * function MyComponent() {
49
49
  * const app = useProductSDK();
50
- * // Use app.wallet, app.storage, etc.
50
+ * // Use app.wallet, app.localStorage, etc.
51
51
  * }
52
52
  * ```
53
53
  */
@@ -113,7 +113,7 @@ type UseWalletReturn = UseWalletState & UseWalletActions;
113
113
  declare function useWallet(): UseWalletReturn;
114
114
 
115
115
  /**
116
- * useStorage hook
116
+ * useLocalStorage hook
117
117
  */
118
118
  /**
119
119
  * Hook for key-value storage operations
@@ -124,7 +124,7 @@ declare function useWallet(): UseWalletReturn;
124
124
  * @example
125
125
  * ```tsx
126
126
  * function ThemeToggle() {
127
- * const [theme, setTheme, { loading }] = useStorage('theme', 'light');
127
+ * const [theme, setTheme, { loading }] = useLocalStorage('theme', 'light');
128
128
  *
129
129
  * if (loading) return <div>Loading...</div>;
130
130
  *
@@ -136,7 +136,7 @@ declare function useWallet(): UseWalletReturn;
136
136
  * }
137
137
  * ```
138
138
  */
139
- declare function useStorage<T = string>(key: string, defaultValue?: T): [T | null, (value: T) => Promise<void>, {
139
+ declare function useLocalStorage<T = string>(key: string, defaultValue?: T): [T | null, (value: T) => Promise<void>, {
140
140
  loading: boolean;
141
141
  error: Error | null;
142
142
  }];
@@ -146,7 +146,7 @@ declare function useStorage<T = string>(key: string, defaultValue?: T): [T | nul
146
146
  * @param key - Storage key
147
147
  * @param defaultValue - Default value
148
148
  */
149
- declare function useStorageString(key: string, defaultValue?: string): [string | null, (value: string) => Promise<void>, {
149
+ declare function useLocalStorageString(key: string, defaultValue?: string): [string | null, (value: string) => Promise<void>, {
150
150
  loading: boolean;
151
151
  }];
152
152
 
@@ -174,4 +174,4 @@ declare function useStorageString(key: string, defaultValue?: string): [string |
174
174
  */
175
175
  declare function useChain<T extends ChainDefinition>(chain: T): TypedApi<T>;
176
176
 
177
- export { ProductSDKContext, ProductSDKProvider, type ProductSDKProviderProps, type UseWalletActions, type UseWalletReturn, type UseWalletState, useChain, useProductSDK, useStorage, useStorageString, useWallet };
177
+ export { ProductSDKContext, ProductSDKProvider, type ProductSDKProviderProps, type UseWalletActions, type UseWalletReturn, type UseWalletState, useChain, useLocalStorage, useLocalStorageString, useProductSDK, useWallet };
@@ -1,4 +1,4 @@
1
- import { createApp } from '../chunk-6W3TCR3W.js';
1
+ import { createApp } from '../chunk-4U2FP26I.js';
2
2
  import { createContext, useContext, useState, useEffect, useCallback, useMemo } from 'react';
3
3
  import { jsx, Fragment } from 'react/jsx-runtime';
4
4
 
@@ -109,7 +109,7 @@ function useWallet() {
109
109
  signMessage
110
110
  };
111
111
  }
112
- function useStorage(key, defaultValue) {
112
+ function useLocalStorage(key, defaultValue) {
113
113
  const app = useProductSDK();
114
114
  const [value, setValue] = useState(null);
115
115
  const [loading, setLoading] = useState(true);
@@ -119,7 +119,7 @@ function useStorage(key, defaultValue) {
119
119
  const loadValue = async () => {
120
120
  try {
121
121
  setLoading(true);
122
- const stored = await app.storage.getJSON(key);
122
+ const stored = await app.localStorage.getJSON(key);
123
123
  if (mounted) {
124
124
  setValue(stored ?? defaultValue ?? null);
125
125
  setLoading(false);
@@ -140,7 +140,7 @@ function useStorage(key, defaultValue) {
140
140
  async (newValue) => {
141
141
  try {
142
142
  setError(null);
143
- await app.storage.setJSON(key, newValue);
143
+ await app.localStorage.setJSON(key, newValue);
144
144
  setValue(newValue);
145
145
  } catch (e) {
146
146
  setError(e instanceof Error ? e : new Error(String(e)));
@@ -151,14 +151,14 @@ function useStorage(key, defaultValue) {
151
151
  );
152
152
  return [value, setStoredValue, { loading, error }];
153
153
  }
154
- function useStorageString(key, defaultValue) {
154
+ function useLocalStorageString(key, defaultValue) {
155
155
  const app = useProductSDK();
156
156
  const [value, setValue] = useState(null);
157
157
  const [loading, setLoading] = useState(true);
158
158
  useEffect(() => {
159
159
  let mounted = true;
160
160
  const loadValue = async () => {
161
- const stored = await app.storage.get(key);
161
+ const stored = await app.localStorage.get(key);
162
162
  if (mounted) {
163
163
  setValue(stored ?? defaultValue ?? null);
164
164
  setLoading(false);
@@ -171,7 +171,7 @@ function useStorageString(key, defaultValue) {
171
171
  }, [app, key, defaultValue]);
172
172
  const setStoredValue = useCallback(
173
173
  async (newValue) => {
174
- await app.storage.set(key, newValue);
174
+ await app.localStorage.set(key, newValue);
175
175
  setValue(newValue);
176
176
  },
177
177
  [app, key]
@@ -185,6 +185,6 @@ function useChain(chain) {
185
185
  }, [app, chain]);
186
186
  }
187
187
 
188
- export { ProductSDKContext, ProductSDKProvider, useChain, useProductSDK, useStorage, useStorageString, useWallet };
188
+ export { ProductSDKContext, ProductSDKProvider, useChain, useLocalStorage, useLocalStorageString, useProductSDK, useWallet };
189
189
  //# sourceMappingURL=index.js.map
190
190
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/context.ts","../../src/react/provider.tsx","../../src/react/useWallet.ts","../../src/react/useStorage.ts","../../src/react/useChain.ts"],"names":["useState","useEffect","useCallback"],"mappings":";;;;AAQO,IAAM,iBAAA,GAAoB,cAA0B,IAAI;AAexD,SAAS,aAAA,GAAqB;AACjC,EAAA,MAAM,GAAA,GAAM,WAAW,iBAAiB,CAAA;AACxC,EAAA,IAAI,CAAC,GAAA,EAAK;AACN,IAAA,MAAM,IAAI,KAAA;AAAA,MACN;AAAA,KAEJ;AAAA,EACJ;AACA,EAAA,OAAO,GAAA;AACX;ACKO,SAAS,kBAAA,CAAmB;AAAA,EAC/B,IAAA;AAAA,EACA,QAAA,GAAW,MAAA;AAAA,EACX,QAAA;AAAA,EACA,QAAA,GAAW;AACf,CAAA,EAA4B;AACxB,EAAA,MAAM,CAAC,GAAA,EAAK,MAAM,CAAA,GAAI,SAAqB,IAAI,CAAA;AAC/C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,IAAI,OAAA,GAAU,IAAA;AAEd,IAAA,SAAA,CAAU,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA,CACvB,IAAA,CAAK,CAAC,UAAA,KAAe;AAClB,MAAA,IAAI,OAAA,EAAS;AACT,QAAA,MAAA,CAAO,UAAU,CAAA;AAAA,MACrB;AAAA,IACJ,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,CAAA,KAAM;AACV,MAAA,IAAI,OAAA,EAAS;AACT,QAAA,QAAA,CAAS,CAAA,YAAa,QAAQ,CAAA,GAAI,IAAI,MAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,MAC1D;AAAA,IACJ,CAAC,CAAA;AAEL,IAAA,OAAO,MAAM;AACT,MAAA,OAAA,GAAU,KAAA;AAAA,IACd,CAAA;AAAA,EACJ,CAAA,EAAG,CAAC,IAAA,EAAM,QAAQ,CAAC,CAAA;AAEnB,EAAA,IAAI,KAAA,EAAO;AACP,IAAA,MAAM,KAAA;AAAA,EACV;AAEA,EAAA,IAAI,CAAC,GAAA,EAAK;AACN,IAAA,uCAAU,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,EACvB;AAEA,EAAA,2BAAQ,iBAAA,CAAkB,QAAA,EAAlB,EAA2B,KAAA,EAAO,KAAM,QAAA,EAAS,CAAA;AAC7D;ACXO,SAAS,SAAA,GAA6B;AACzC,EAAA,MAAM,MAAM,aAAA,EAAc;AAE1B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,QAAAA,CAAyB;AAAA,IAC/C,WAAA,EAAa,KAAA;AAAA,IACb,YAAA,EAAc,KAAA;AAAA,IACd,UAAU,EAAC;AAAA,IACX,eAAA,EAAiB,IAAA;AAAA,IACjB,KAAA,EAAO;AAAA,GACV,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,YAAY,YAAY;AACpC,IAAA,QAAA,CAAS,CAAC,OAAO,EAAE,GAAG,GAAG,YAAA,EAAc,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK,CAAE,CAAA;AAC3D,IAAA,IAAI;AACA,MAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,MAAA,CAAO,OAAA,EAAQ;AACxC,MAAA,QAAA,CAAS,CAAC,CAAA,MAAO;AAAA,QACb,GAAG,CAAA;AAAA,QACH,WAAA,EAAa,IAAA;AAAA,QACb,YAAA,EAAc,KAAA;AAAA,QACd,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,eAAA,EAAiB,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK;AAAA,OAC3C,CAAE,CAAA;AAAA,IACN,SAAS,CAAA,EAAG;AACR,MAAA,QAAA,CAAS,CAAC,CAAA,MAAO;AAAA,QACb,GAAG,CAAA;AAAA,QACH,YAAA,EAAc,KAAA;AAAA,QACd,KAAA,EAAO,aAAa,KAAA,GAAQ,CAAA,GAAI,IAAI,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC;AAAA,OACvD,CAAE,CAAA;AAAA,IACN;AAAA,EACJ,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,MAAM,UAAA,GAAa,YAAY,YAAY;AACvC,IAAA,MAAM,GAAA,CAAI,OAAO,UAAA,EAAW;AAC5B,IAAA,QAAA,CAAS;AAAA,MACL,WAAA,EAAa,KAAA;AAAA,MACb,YAAA,EAAc,KAAA;AAAA,MACd,UAAU,EAAC;AAAA,MACX,eAAA,EAAiB,IAAA;AAAA,MACjB,KAAA,EAAO;AAAA,KACV,CAAA;AAAA,EACL,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,MAAM,aAAA,GAAgB,WAAA;AAAA,IAClB,CAAC,OAAA,KAAoB;AACjB,MAAA,GAAA,CAAI,MAAA,CAAO,cAAc,OAAO,CAAA;AAChC,MAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAA,KAAY,OAAO,CAAA,IAAK,IAAA;AACrE,MAAA,QAAA,CAAS,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,eAAA,EAAiB,SAAQ,CAAE,CAAA;AAAA,IACxD,CAAA;AAAA,IACA,CAAC,GAAA,EAAK,KAAA,CAAM,QAAQ;AAAA,GACxB;AAEA,EAAA,MAAM,WAAA,GAAc,WAAA;AAAA,IAChB,OAAO,OAAA,KAAiC;AACpC,MAAA,OAAO,GAAA,CAAI,MAAA,CAAO,WAAA,CAAY,OAAO,CAAA;AAAA,IACzC,CAAA;AAAA,IACA,CAAC,GAAG;AAAA,GACR;AAGA,EAAAC,UAAU,MAAM;AACZ,IAAA,MAAM,WAAA,GAAc,GAAA,CAAI,MAAA,CAAO,eAAA,CAAgB,CAAC,OAAA,KAAY;AACxD,MAAA,QAAA,CAAS,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,eAAA,EAAiB,SAAQ,CAAE,CAAA;AAAA,IACxD,CAAC,CAAA;AACD,IAAA,OAAO,WAAA;AAAA,EACX,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,OAAO;AAAA,IACH,GAAG,KAAA;AAAA,IACH,OAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACJ;AACJ;AC7GO,SAAS,UAAA,CACZ,KACA,YAAA,EACkF;AAClF,EAAA,MAAM,MAAM,aAAA,EAAc;AAE1B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAID,SAAmB,IAAI,CAAA;AACjD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,SAAS,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,SAAuB,IAAI,CAAA;AAGrD,EAAAC,UAAU,MAAM;AACZ,IAAA,IAAI,OAAA,GAAU,IAAA;AAEd,IAAA,MAAM,YAAY,YAAY;AAC1B,MAAA,IAAI;AACA,QAAA,UAAA,CAAW,IAAI,CAAA;AACf,QAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,OAAA,CAAQ,QAAW,GAAG,CAAA;AAC/C,QAAA,IAAI,OAAA,EAAS;AACT,UAAA,QAAA,CAAS,MAAA,IAAU,gBAAgB,IAAI,CAAA;AACvC,UAAA,UAAA,CAAW,KAAK,CAAA;AAAA,QACpB;AAAA,MACJ,SAAS,CAAA,EAAG;AACR,QAAA,IAAI,OAAA,EAAS;AACT,UAAA,QAAA,CAAS,CAAA,YAAa,QAAQ,CAAA,GAAI,IAAI,MAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AACtD,UAAA,UAAA,CAAW,KAAK,CAAA;AAAA,QACpB;AAAA,MACJ;AAAA,IACJ,CAAA;AAEA,IAAA,SAAA,EAAU;AAEV,IAAA,OAAO,MAAM;AACT,MAAA,OAAA,GAAU,KAAA;AAAA,IACd,CAAA;AAAA,EACJ,CAAA,EAAG,CAAC,GAAA,EAAK,GAAA,EAAK,YAAY,CAAC,CAAA;AAE3B,EAAA,MAAM,cAAA,GAAiBC,WAAAA;AAAA,IACnB,OAAO,QAAA,KAAgB;AACnB,MAAA,IAAI;AACA,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,MAAM,GAAA,CAAI,OAAA,CAAQ,OAAA,CAAQ,GAAA,EAAK,QAAQ,CAAA;AACvC,QAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,MACrB,SAAS,CAAA,EAAG;AACR,QAAA,QAAA,CAAS,CAAA,YAAa,QAAQ,CAAA,GAAI,IAAI,MAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AACtD,QAAA,MAAM,CAAA;AAAA,MACV;AAAA,IACJ,CAAA;AAAA,IACA,CAAC,KAAK,GAAG;AAAA,GACb;AAEA,EAAA,OAAO,CAAC,KAAA,EAAO,cAAA,EAAgB,EAAE,OAAA,EAAS,OAAO,CAAA;AACrD;AAQO,SAAS,gBAAA,CACZ,KACA,YAAA,EACuE;AACvE,EAAA,MAAM,MAAM,aAAA,EAAc;AAE1B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIF,SAAwB,IAAI,CAAA;AACtD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,SAAS,IAAI,CAAA;AAE3C,EAAAC,UAAU,MAAM;AACZ,IAAA,IAAI,OAAA,GAAU,IAAA;AAEd,IAAA,MAAM,YAAY,YAAY;AAC1B,MAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,OAAA,CAAQ,IAAI,GAAG,CAAA;AACxC,MAAA,IAAI,OAAA,EAAS;AACT,QAAA,QAAA,CAAS,MAAA,IAAU,gBAAgB,IAAI,CAAA;AACvC,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA,MACpB;AAAA,IACJ,CAAA;AAEA,IAAA,SAAA,EAAU;AAEV,IAAA,OAAO,MAAM;AACT,MAAA,OAAA,GAAU,KAAA;AAAA,IACd,CAAA;AAAA,EACJ,CAAA,EAAG,CAAC,GAAA,EAAK,GAAA,EAAK,YAAY,CAAC,CAAA;AAE3B,EAAA,MAAM,cAAA,GAAiBC,WAAAA;AAAA,IACnB,OAAO,QAAA,KAAqB;AACxB,MAAA,MAAM,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,QAAQ,CAAA;AACnC,MAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,IACrB,CAAA;AAAA,IACA,CAAC,KAAK,GAAG;AAAA,GACb;AAEA,EAAA,OAAO,CAAC,KAAA,EAAO,cAAA,EAAgB,EAAE,SAAS,CAAA;AAC9C;AClGO,SAAS,SAAoC,KAAA,EAAuB;AACvE,EAAA,MAAM,MAAM,aAAA,EAAc;AAE1B,EAAA,OAAO,QAAQ,MAAM;AACjB,IAAA,OAAO,GAAA,CAAI,KAAA,CAAM,SAAA,CAAU,KAAK,CAAA;AAAA,EACpC,CAAA,EAAG,CAAC,GAAA,EAAK,KAAK,CAAC,CAAA;AACnB","file":"index.js","sourcesContent":["/**\n * React context for Product SDK\n */\n\nimport { createContext, useContext } from \"react\";\nimport type { App } from \"../core/types.js\";\n\n/** Context for the Product SDK app instance */\nexport const ProductSDKContext = createContext<App | null>(null);\n\n/**\n * Hook to access the Product SDK app instance\n *\n * @throws If used outside of ProductSDKProvider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const app = useProductSDK();\n * // Use app.wallet, app.storage, etc.\n * }\n * ```\n */\nexport function useProductSDK(): App {\n const app = useContext(ProductSDKContext);\n if (!app) {\n throw new Error(\n \"useProductSDK must be used within a ProductSDKProvider. \" +\n 'Wrap your app with <ProductSDKProvider name=\"your-app\">.',\n );\n }\n return app;\n}\n","/**\n * ProductSDKProvider component\n */\n\nimport React, { useEffect, useState, type ReactNode } from \"react\";\nimport { ProductSDKContext } from \"./context.js\";\nimport { createApp } from \"../core/createApp.js\";\nimport type { App, LogLevel } from \"../core/types.js\";\n\n/** Props for ProductSDKProvider */\nexport interface ProductSDKProviderProps {\n /** Application name - used for storage namespacing and product account derivation */\n name: string;\n /** Log level (default: 'info') */\n logLevel?: LogLevel;\n /** Child components */\n children: ReactNode;\n /** Fallback to show while loading */\n fallback?: ReactNode;\n}\n\n/**\n * Provider component that initializes the Product SDK\n *\n * @example\n * ```tsx\n * import { ProductSDKProvider } from '@parity/product-sdk/react';\n *\n * function App() {\n * return (\n * <ProductSDKProvider name=\"my-app\" fallback={<Loading />}>\n * <MyApp />\n * </ProductSDKProvider>\n * );\n * }\n * ```\n */\nexport function ProductSDKProvider({\n name,\n logLevel = \"info\",\n children,\n fallback = null,\n}: ProductSDKProviderProps) {\n const [app, setApp] = useState<App | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let mounted = true;\n\n createApp({ name, logLevel })\n .then((createdApp) => {\n if (mounted) {\n setApp(createdApp);\n }\n })\n .catch((e) => {\n if (mounted) {\n setError(e instanceof Error ? e : new Error(String(e)));\n }\n });\n\n return () => {\n mounted = false;\n };\n }, [name, logLevel]);\n\n if (error) {\n throw error;\n }\n\n if (!app) {\n return <>{fallback}</>;\n }\n\n return <ProductSDKContext.Provider value={app}>{children}</ProductSDKContext.Provider>;\n}\n","/**\n * useWallet hook\n */\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { useProductSDK } from \"./context.js\";\nimport type { Account } from \"../core/types.js\";\n\n/** Wallet hook state */\nexport interface UseWalletState {\n /** Whether wallet is connected */\n isConnected: boolean;\n /** Whether connection is in progress */\n isConnecting: boolean;\n /** Available accounts */\n accounts: Account[];\n /** Currently selected account */\n selectedAccount: Account | null;\n /** Last error */\n error: Error | null;\n}\n\n/** Wallet hook actions */\nexport interface UseWalletActions {\n /** Connect to wallet */\n connect: () => Promise<void>;\n /** Disconnect from wallet */\n disconnect: () => Promise<void>;\n /** Select an account */\n selectAccount: (address: string) => void;\n /** Sign a message */\n signMessage: (message: string | Uint8Array) => Promise<Uint8Array>;\n}\n\n/** Return type of useWallet */\nexport type UseWalletReturn = UseWalletState & UseWalletActions;\n\n/**\n * Hook for wallet connection and signing\n *\n * @example\n * ```tsx\n * function WalletButton() {\n * const { isConnected, accounts, connect, disconnect, selectAccount } = useWallet();\n *\n * if (!isConnected) {\n * return <button onClick={connect}>Connect Wallet</button>;\n * }\n *\n * return (\n * <div>\n * <select onChange={(e) => selectAccount(e.target.value)}>\n * {accounts.map((a) => (\n * <option key={a.address} value={a.address}>\n * {a.name || a.address}\n * </option>\n * ))}\n * </select>\n * <button onClick={disconnect}>Disconnect</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useWallet(): UseWalletReturn {\n const app = useProductSDK();\n\n const [state, setState] = useState<UseWalletState>({\n isConnected: false,\n isConnecting: false,\n accounts: [],\n selectedAccount: null,\n error: null,\n });\n\n const connect = useCallback(async () => {\n setState((s) => ({ ...s, isConnecting: true, error: null }));\n try {\n const result = await app.wallet.connect();\n setState((s) => ({\n ...s,\n isConnected: true,\n isConnecting: false,\n accounts: result.accounts,\n selectedAccount: result.accounts[0] || null,\n }));\n } catch (e) {\n setState((s) => ({\n ...s,\n isConnecting: false,\n error: e instanceof Error ? e : new Error(String(e)),\n }));\n }\n }, [app]);\n\n const disconnect = useCallback(async () => {\n await app.wallet.disconnect();\n setState({\n isConnected: false,\n isConnecting: false,\n accounts: [],\n selectedAccount: null,\n error: null,\n });\n }, [app]);\n\n const selectAccount = useCallback(\n (address: string) => {\n app.wallet.selectAccount(address);\n const account = state.accounts.find((a) => a.address === address) || null;\n setState((s) => ({ ...s, selectedAccount: account }));\n },\n [app, state.accounts],\n );\n\n const signMessage = useCallback(\n async (message: string | Uint8Array) => {\n return app.wallet.signMessage(message);\n },\n [app],\n );\n\n // Subscribe to account changes\n useEffect(() => {\n const unsubscribe = app.wallet.onAccountChange((account) => {\n setState((s) => ({ ...s, selectedAccount: account }));\n });\n return unsubscribe;\n }, [app]);\n\n return {\n ...state,\n connect,\n disconnect,\n selectAccount,\n signMessage,\n };\n}\n","/**\n * useStorage hook\n */\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { useProductSDK } from \"./context.js\";\n\n/**\n * Hook for key-value storage operations\n *\n * @param key - Storage key\n * @param defaultValue - Default value if key doesn't exist\n *\n * @example\n * ```tsx\n * function ThemeToggle() {\n * const [theme, setTheme, { loading }] = useStorage('theme', 'light');\n *\n * if (loading) return <div>Loading...</div>;\n *\n * return (\n * <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>\n * Current: {theme}\n * </button>\n * );\n * }\n * ```\n */\nexport function useStorage<T = string>(\n key: string,\n defaultValue?: T,\n): [T | null, (value: T) => Promise<void>, { loading: boolean; error: Error | null }] {\n const app = useProductSDK();\n\n const [value, setValue] = useState<T | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n // Load initial value\n useEffect(() => {\n let mounted = true;\n\n const loadValue = async () => {\n try {\n setLoading(true);\n const stored = await app.storage.getJSON<T>(key);\n if (mounted) {\n setValue(stored ?? defaultValue ?? null);\n setLoading(false);\n }\n } catch (e) {\n if (mounted) {\n setError(e instanceof Error ? e : new Error(String(e)));\n setLoading(false);\n }\n }\n };\n\n loadValue();\n\n return () => {\n mounted = false;\n };\n }, [app, key, defaultValue]);\n\n const setStoredValue = useCallback(\n async (newValue: T) => {\n try {\n setError(null);\n await app.storage.setJSON(key, newValue);\n setValue(newValue);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n throw e;\n }\n },\n [app, key],\n );\n\n return [value, setStoredValue, { loading, error }];\n}\n\n/**\n * Hook for string storage (simpler API)\n *\n * @param key - Storage key\n * @param defaultValue - Default value\n */\nexport function useStorageString(\n key: string,\n defaultValue?: string,\n): [string | null, (value: string) => Promise<void>, { loading: boolean }] {\n const app = useProductSDK();\n\n const [value, setValue] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let mounted = true;\n\n const loadValue = async () => {\n const stored = await app.storage.get(key);\n if (mounted) {\n setValue(stored ?? defaultValue ?? null);\n setLoading(false);\n }\n };\n\n loadValue();\n\n return () => {\n mounted = false;\n };\n }, [app, key, defaultValue]);\n\n const setStoredValue = useCallback(\n async (newValue: string) => {\n await app.storage.set(key, newValue);\n setValue(newValue);\n },\n [app, key],\n );\n\n return [value, setStoredValue, { loading }];\n}\n","/**\n * useChain hook\n */\n\nimport { useMemo } from \"react\";\nimport { useProductSDK } from \"./context.js\";\nimport type { ChainDefinition, TypedApi } from \"../core/types.js\";\n\n/**\n * Hook to get a typed chain client\n *\n * @param chain - Chain descriptor (PAPI ChainDefinition)\n *\n * @example\n * ```tsx\n * import { paseo_asset_hub } from '@parity/product-sdk-descriptors/paseo-asset-hub';\n * import { useChain } from '@parity/product-sdk/react';\n *\n * function AssetHubBalance() {\n * const assetHub = useChain(paseo_asset_hub);\n *\n * // assetHub is typed for Asset Hub queries\n * const balance = await assetHub.query.System.Account.getValue(address);\n * }\n * ```\n */\nexport function useChain<T extends ChainDefinition>(chain: T): TypedApi<T> {\n const app = useProductSDK();\n\n return useMemo(() => {\n return app.chain.getClient(chain);\n }, [app, chain]);\n}\n"]}
1
+ {"version":3,"sources":["../../src/react/context.ts","../../src/react/provider.tsx","../../src/react/useWallet.ts","../../src/react/useLocalStorage.ts","../../src/react/useChain.ts"],"names":["useState","useEffect","useCallback"],"mappings":";;;;AAQO,IAAM,iBAAA,GAAoB,cAA0B,IAAI;AAexD,SAAS,aAAA,GAAqB;AACjC,EAAA,MAAM,GAAA,GAAM,WAAW,iBAAiB,CAAA;AACxC,EAAA,IAAI,CAAC,GAAA,EAAK;AACN,IAAA,MAAM,IAAI,KAAA;AAAA,MACN;AAAA,KAEJ;AAAA,EACJ;AACA,EAAA,OAAO,GAAA;AACX;ACKO,SAAS,kBAAA,CAAmB;AAAA,EAC/B,IAAA;AAAA,EACA,QAAA,GAAW,MAAA;AAAA,EACX,QAAA;AAAA,EACA,QAAA,GAAW;AACf,CAAA,EAA4B;AACxB,EAAA,MAAM,CAAC,GAAA,EAAK,MAAM,CAAA,GAAI,SAAqB,IAAI,CAAA;AAC/C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,IAAI,OAAA,GAAU,IAAA;AAEd,IAAA,SAAA,CAAU,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA,CACvB,IAAA,CAAK,CAAC,UAAA,KAAe;AAClB,MAAA,IAAI,OAAA,EAAS;AACT,QAAA,MAAA,CAAO,UAAU,CAAA;AAAA,MACrB;AAAA,IACJ,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,CAAA,KAAM;AACV,MAAA,IAAI,OAAA,EAAS;AACT,QAAA,QAAA,CAAS,CAAA,YAAa,QAAQ,CAAA,GAAI,IAAI,MAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,MAC1D;AAAA,IACJ,CAAC,CAAA;AAEL,IAAA,OAAO,MAAM;AACT,MAAA,OAAA,GAAU,KAAA;AAAA,IACd,CAAA;AAAA,EACJ,CAAA,EAAG,CAAC,IAAA,EAAM,QAAQ,CAAC,CAAA;AAEnB,EAAA,IAAI,KAAA,EAAO;AACP,IAAA,MAAM,KAAA;AAAA,EACV;AAEA,EAAA,IAAI,CAAC,GAAA,EAAK;AACN,IAAA,uCAAU,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,EACvB;AAEA,EAAA,2BAAQ,iBAAA,CAAkB,QAAA,EAAlB,EAA2B,KAAA,EAAO,KAAM,QAAA,EAAS,CAAA;AAC7D;ACXO,SAAS,SAAA,GAA6B;AACzC,EAAA,MAAM,MAAM,aAAA,EAAc;AAE1B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,QAAAA,CAAyB;AAAA,IAC/C,WAAA,EAAa,KAAA;AAAA,IACb,YAAA,EAAc,KAAA;AAAA,IACd,UAAU,EAAC;AAAA,IACX,eAAA,EAAiB,IAAA;AAAA,IACjB,KAAA,EAAO;AAAA,GACV,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,YAAY,YAAY;AACpC,IAAA,QAAA,CAAS,CAAC,OAAO,EAAE,GAAG,GAAG,YAAA,EAAc,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK,CAAE,CAAA;AAC3D,IAAA,IAAI;AACA,MAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,MAAA,CAAO,OAAA,EAAQ;AACxC,MAAA,QAAA,CAAS,CAAC,CAAA,MAAO;AAAA,QACb,GAAG,CAAA;AAAA,QACH,WAAA,EAAa,IAAA;AAAA,QACb,YAAA,EAAc,KAAA;AAAA,QACd,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,eAAA,EAAiB,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK;AAAA,OAC3C,CAAE,CAAA;AAAA,IACN,SAAS,CAAA,EAAG;AACR,MAAA,QAAA,CAAS,CAAC,CAAA,MAAO;AAAA,QACb,GAAG,CAAA;AAAA,QACH,YAAA,EAAc,KAAA;AAAA,QACd,KAAA,EAAO,aAAa,KAAA,GAAQ,CAAA,GAAI,IAAI,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC;AAAA,OACvD,CAAE,CAAA;AAAA,IACN;AAAA,EACJ,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,MAAM,UAAA,GAAa,YAAY,YAAY;AACvC,IAAA,MAAM,GAAA,CAAI,OAAO,UAAA,EAAW;AAC5B,IAAA,QAAA,CAAS;AAAA,MACL,WAAA,EAAa,KAAA;AAAA,MACb,YAAA,EAAc,KAAA;AAAA,MACd,UAAU,EAAC;AAAA,MACX,eAAA,EAAiB,IAAA;AAAA,MACjB,KAAA,EAAO;AAAA,KACV,CAAA;AAAA,EACL,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,MAAM,aAAA,GAAgB,WAAA;AAAA,IAClB,CAAC,OAAA,KAAoB;AACjB,MAAA,GAAA,CAAI,MAAA,CAAO,cAAc,OAAO,CAAA;AAChC,MAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAA,KAAY,OAAO,CAAA,IAAK,IAAA;AACrE,MAAA,QAAA,CAAS,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,eAAA,EAAiB,SAAQ,CAAE,CAAA;AAAA,IACxD,CAAA;AAAA,IACA,CAAC,GAAA,EAAK,KAAA,CAAM,QAAQ;AAAA,GACxB;AAEA,EAAA,MAAM,WAAA,GAAc,WAAA;AAAA,IAChB,OAAO,OAAA,KAAiC;AACpC,MAAA,OAAO,GAAA,CAAI,MAAA,CAAO,WAAA,CAAY,OAAO,CAAA;AAAA,IACzC,CAAA;AAAA,IACA,CAAC,GAAG;AAAA,GACR;AAGA,EAAAC,UAAU,MAAM;AACZ,IAAA,MAAM,WAAA,GAAc,GAAA,CAAI,MAAA,CAAO,eAAA,CAAgB,CAAC,OAAA,KAAY;AACxD,MAAA,QAAA,CAAS,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,eAAA,EAAiB,SAAQ,CAAE,CAAA;AAAA,IACxD,CAAC,CAAA;AACD,IAAA,OAAO,WAAA;AAAA,EACX,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,OAAO;AAAA,IACH,GAAG,KAAA;AAAA,IACH,OAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACJ;AACJ;AC7GO,SAAS,eAAA,CACZ,KACA,YAAA,EACkF;AAClF,EAAA,MAAM,MAAM,aAAA,EAAc;AAE1B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAID,SAAmB,IAAI,CAAA;AACjD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,SAAS,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,SAAuB,IAAI,CAAA;AAGrD,EAAAC,UAAU,MAAM;AACZ,IAAA,IAAI,OAAA,GAAU,IAAA;AAEd,IAAA,MAAM,YAAY,YAAY;AAC1B,MAAA,IAAI;AACA,QAAA,UAAA,CAAW,IAAI,CAAA;AACf,QAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,YAAA,CAAa,QAAW,GAAG,CAAA;AACpD,QAAA,IAAI,OAAA,EAAS;AACT,UAAA,QAAA,CAAS,MAAA,IAAU,gBAAgB,IAAI,CAAA;AACvC,UAAA,UAAA,CAAW,KAAK,CAAA;AAAA,QACpB;AAAA,MACJ,SAAS,CAAA,EAAG;AACR,QAAA,IAAI,OAAA,EAAS;AACT,UAAA,QAAA,CAAS,CAAA,YAAa,QAAQ,CAAA,GAAI,IAAI,MAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AACtD,UAAA,UAAA,CAAW,KAAK,CAAA;AAAA,QACpB;AAAA,MACJ;AAAA,IACJ,CAAA;AAEA,IAAA,SAAA,EAAU;AAEV,IAAA,OAAO,MAAM;AACT,MAAA,OAAA,GAAU,KAAA;AAAA,IACd,CAAA;AAAA,EACJ,CAAA,EAAG,CAAC,GAAA,EAAK,GAAA,EAAK,YAAY,CAAC,CAAA;AAE3B,EAAA,MAAM,cAAA,GAAiBC,WAAAA;AAAA,IACnB,OAAO,QAAA,KAAgB;AACnB,MAAA,IAAI;AACA,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,MAAM,GAAA,CAAI,YAAA,CAAa,OAAA,CAAQ,GAAA,EAAK,QAAQ,CAAA;AAC5C,QAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,MACrB,SAAS,CAAA,EAAG;AACR,QAAA,QAAA,CAAS,CAAA,YAAa,QAAQ,CAAA,GAAI,IAAI,MAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AACtD,QAAA,MAAM,CAAA;AAAA,MACV;AAAA,IACJ,CAAA;AAAA,IACA,CAAC,KAAK,GAAG;AAAA,GACb;AAEA,EAAA,OAAO,CAAC,KAAA,EAAO,cAAA,EAAgB,EAAE,OAAA,EAAS,OAAO,CAAA;AACrD;AAQO,SAAS,qBAAA,CACZ,KACA,YAAA,EACuE;AACvE,EAAA,MAAM,MAAM,aAAA,EAAc;AAE1B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIF,SAAwB,IAAI,CAAA;AACtD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,SAAS,IAAI,CAAA;AAE3C,EAAAC,UAAU,MAAM;AACZ,IAAA,IAAI,OAAA,GAAU,IAAA;AAEd,IAAA,MAAM,YAAY,YAAY;AAC1B,MAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,YAAA,CAAa,IAAI,GAAG,CAAA;AAC7C,MAAA,IAAI,OAAA,EAAS;AACT,QAAA,QAAA,CAAS,MAAA,IAAU,gBAAgB,IAAI,CAAA;AACvC,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA,MACpB;AAAA,IACJ,CAAA;AAEA,IAAA,SAAA,EAAU;AAEV,IAAA,OAAO,MAAM;AACT,MAAA,OAAA,GAAU,KAAA;AAAA,IACd,CAAA;AAAA,EACJ,CAAA,EAAG,CAAC,GAAA,EAAK,GAAA,EAAK,YAAY,CAAC,CAAA;AAE3B,EAAA,MAAM,cAAA,GAAiBC,WAAAA;AAAA,IACnB,OAAO,QAAA,KAAqB;AACxB,MAAA,MAAM,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,GAAA,EAAK,QAAQ,CAAA;AACxC,MAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,IACrB,CAAA;AAAA,IACA,CAAC,KAAK,GAAG;AAAA,GACb;AAEA,EAAA,OAAO,CAAC,KAAA,EAAO,cAAA,EAAgB,EAAE,SAAS,CAAA;AAC9C;AClGO,SAAS,SAAoC,KAAA,EAAuB;AACvE,EAAA,MAAM,MAAM,aAAA,EAAc;AAE1B,EAAA,OAAO,QAAQ,MAAM;AACjB,IAAA,OAAO,GAAA,CAAI,KAAA,CAAM,SAAA,CAAU,KAAK,CAAA;AAAA,EACpC,CAAA,EAAG,CAAC,GAAA,EAAK,KAAK,CAAC,CAAA;AACnB","file":"index.js","sourcesContent":["/**\n * React context for Product SDK\n */\n\nimport { createContext, useContext } from \"react\";\nimport type { App } from \"../core/types.js\";\n\n/** Context for the Product SDK app instance */\nexport const ProductSDKContext = createContext<App | null>(null);\n\n/**\n * Hook to access the Product SDK app instance\n *\n * @throws If used outside of ProductSDKProvider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const app = useProductSDK();\n * // Use app.wallet, app.localStorage, etc.\n * }\n * ```\n */\nexport function useProductSDK(): App {\n const app = useContext(ProductSDKContext);\n if (!app) {\n throw new Error(\n \"useProductSDK must be used within a ProductSDKProvider. \" +\n 'Wrap your app with <ProductSDKProvider name=\"your-app\">.',\n );\n }\n return app;\n}\n","/**\n * ProductSDKProvider component\n */\n\nimport React, { useEffect, useState, type ReactNode } from \"react\";\nimport { ProductSDKContext } from \"./context.js\";\nimport { createApp } from \"../core/createApp.js\";\nimport type { App, LogLevel } from \"../core/types.js\";\n\n/** Props for ProductSDKProvider */\nexport interface ProductSDKProviderProps {\n /** Application name - used for storage namespacing and product account derivation */\n name: string;\n /** Log level (default: 'info') */\n logLevel?: LogLevel;\n /** Child components */\n children: ReactNode;\n /** Fallback to show while loading */\n fallback?: ReactNode;\n}\n\n/**\n * Provider component that initializes the Product SDK\n *\n * @example\n * ```tsx\n * import { ProductSDKProvider } from '@parity/product-sdk/react';\n *\n * function App() {\n * return (\n * <ProductSDKProvider name=\"my-app\" fallback={<Loading />}>\n * <MyApp />\n * </ProductSDKProvider>\n * );\n * }\n * ```\n */\nexport function ProductSDKProvider({\n name,\n logLevel = \"info\",\n children,\n fallback = null,\n}: ProductSDKProviderProps) {\n const [app, setApp] = useState<App | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let mounted = true;\n\n createApp({ name, logLevel })\n .then((createdApp) => {\n if (mounted) {\n setApp(createdApp);\n }\n })\n .catch((e) => {\n if (mounted) {\n setError(e instanceof Error ? e : new Error(String(e)));\n }\n });\n\n return () => {\n mounted = false;\n };\n }, [name, logLevel]);\n\n if (error) {\n throw error;\n }\n\n if (!app) {\n return <>{fallback}</>;\n }\n\n return <ProductSDKContext.Provider value={app}>{children}</ProductSDKContext.Provider>;\n}\n","/**\n * useWallet hook\n */\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { useProductSDK } from \"./context.js\";\nimport type { Account } from \"../core/types.js\";\n\n/** Wallet hook state */\nexport interface UseWalletState {\n /** Whether wallet is connected */\n isConnected: boolean;\n /** Whether connection is in progress */\n isConnecting: boolean;\n /** Available accounts */\n accounts: Account[];\n /** Currently selected account */\n selectedAccount: Account | null;\n /** Last error */\n error: Error | null;\n}\n\n/** Wallet hook actions */\nexport interface UseWalletActions {\n /** Connect to wallet */\n connect: () => Promise<void>;\n /** Disconnect from wallet */\n disconnect: () => Promise<void>;\n /** Select an account */\n selectAccount: (address: string) => void;\n /** Sign a message */\n signMessage: (message: string | Uint8Array) => Promise<Uint8Array>;\n}\n\n/** Return type of useWallet */\nexport type UseWalletReturn = UseWalletState & UseWalletActions;\n\n/**\n * Hook for wallet connection and signing\n *\n * @example\n * ```tsx\n * function WalletButton() {\n * const { isConnected, accounts, connect, disconnect, selectAccount } = useWallet();\n *\n * if (!isConnected) {\n * return <button onClick={connect}>Connect Wallet</button>;\n * }\n *\n * return (\n * <div>\n * <select onChange={(e) => selectAccount(e.target.value)}>\n * {accounts.map((a) => (\n * <option key={a.address} value={a.address}>\n * {a.name || a.address}\n * </option>\n * ))}\n * </select>\n * <button onClick={disconnect}>Disconnect</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useWallet(): UseWalletReturn {\n const app = useProductSDK();\n\n const [state, setState] = useState<UseWalletState>({\n isConnected: false,\n isConnecting: false,\n accounts: [],\n selectedAccount: null,\n error: null,\n });\n\n const connect = useCallback(async () => {\n setState((s) => ({ ...s, isConnecting: true, error: null }));\n try {\n const result = await app.wallet.connect();\n setState((s) => ({\n ...s,\n isConnected: true,\n isConnecting: false,\n accounts: result.accounts,\n selectedAccount: result.accounts[0] || null,\n }));\n } catch (e) {\n setState((s) => ({\n ...s,\n isConnecting: false,\n error: e instanceof Error ? e : new Error(String(e)),\n }));\n }\n }, [app]);\n\n const disconnect = useCallback(async () => {\n await app.wallet.disconnect();\n setState({\n isConnected: false,\n isConnecting: false,\n accounts: [],\n selectedAccount: null,\n error: null,\n });\n }, [app]);\n\n const selectAccount = useCallback(\n (address: string) => {\n app.wallet.selectAccount(address);\n const account = state.accounts.find((a) => a.address === address) || null;\n setState((s) => ({ ...s, selectedAccount: account }));\n },\n [app, state.accounts],\n );\n\n const signMessage = useCallback(\n async (message: string | Uint8Array) => {\n return app.wallet.signMessage(message);\n },\n [app],\n );\n\n // Subscribe to account changes\n useEffect(() => {\n const unsubscribe = app.wallet.onAccountChange((account) => {\n setState((s) => ({ ...s, selectedAccount: account }));\n });\n return unsubscribe;\n }, [app]);\n\n return {\n ...state,\n connect,\n disconnect,\n selectAccount,\n signMessage,\n };\n}\n","/**\n * useLocalStorage hook\n */\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { useProductSDK } from \"./context.js\";\n\n/**\n * Hook for key-value storage operations\n *\n * @param key - Storage key\n * @param defaultValue - Default value if key doesn't exist\n *\n * @example\n * ```tsx\n * function ThemeToggle() {\n * const [theme, setTheme, { loading }] = useLocalStorage('theme', 'light');\n *\n * if (loading) return <div>Loading...</div>;\n *\n * return (\n * <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>\n * Current: {theme}\n * </button>\n * );\n * }\n * ```\n */\nexport function useLocalStorage<T = string>(\n key: string,\n defaultValue?: T,\n): [T | null, (value: T) => Promise<void>, { loading: boolean; error: Error | null }] {\n const app = useProductSDK();\n\n const [value, setValue] = useState<T | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n // Load initial value\n useEffect(() => {\n let mounted = true;\n\n const loadValue = async () => {\n try {\n setLoading(true);\n const stored = await app.localStorage.getJSON<T>(key);\n if (mounted) {\n setValue(stored ?? defaultValue ?? null);\n setLoading(false);\n }\n } catch (e) {\n if (mounted) {\n setError(e instanceof Error ? e : new Error(String(e)));\n setLoading(false);\n }\n }\n };\n\n loadValue();\n\n return () => {\n mounted = false;\n };\n }, [app, key, defaultValue]);\n\n const setStoredValue = useCallback(\n async (newValue: T) => {\n try {\n setError(null);\n await app.localStorage.setJSON(key, newValue);\n setValue(newValue);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n throw e;\n }\n },\n [app, key],\n );\n\n return [value, setStoredValue, { loading, error }];\n}\n\n/**\n * Hook for string storage (simpler API)\n *\n * @param key - Storage key\n * @param defaultValue - Default value\n */\nexport function useLocalStorageString(\n key: string,\n defaultValue?: string,\n): [string | null, (value: string) => Promise<void>, { loading: boolean }] {\n const app = useProductSDK();\n\n const [value, setValue] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let mounted = true;\n\n const loadValue = async () => {\n const stored = await app.localStorage.get(key);\n if (mounted) {\n setValue(stored ?? defaultValue ?? null);\n setLoading(false);\n }\n };\n\n loadValue();\n\n return () => {\n mounted = false;\n };\n }, [app, key, defaultValue]);\n\n const setStoredValue = useCallback(\n async (newValue: string) => {\n await app.localStorage.set(key, newValue);\n setValue(newValue);\n },\n [app, key],\n );\n\n return [value, setStoredValue, { loading }];\n}\n","/**\n * useChain hook\n */\n\nimport { useMemo } from \"react\";\nimport { useProductSDK } from \"./context.js\";\nimport type { ChainDefinition, TypedApi } from \"../core/types.js\";\n\n/**\n * Hook to get a typed chain client\n *\n * @param chain - Chain descriptor (PAPI ChainDefinition)\n *\n * @example\n * ```tsx\n * import { paseo_asset_hub } from '@parity/product-sdk-descriptors/paseo-asset-hub';\n * import { useChain } from '@parity/product-sdk/react';\n *\n * function AssetHubBalance() {\n * const assetHub = useChain(paseo_asset_hub);\n *\n * // assetHub is typed for Asset Hub queries\n * const balance = await assetHub.query.System.Account.getValue(address);\n * }\n * ```\n */\nexport function useChain<T extends ChainDefinition>(chain: T): TypedApi<T> {\n const app = useProductSDK();\n\n return useMemo(() => {\n return app.chain.getClient(chain);\n }, [app, chain]);\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { LogLevel } from '@parity/product-sdk-logger';
2
- import { BulletinEnvironment } from '@parity/product-sdk-bulletin';
2
+ import { CloudStorageEnvironment } from '@parity/product-sdk-cloud-storage';
3
3
  import { ChainClient } from '@parity/product-sdk-chain-client';
4
4
  import { ChainDefinition, TypedApi, PolkadotClient } from 'polkadot-api';
5
5
 
@@ -7,10 +7,10 @@ import { ChainDefinition, TypedApi, PolkadotClient } from 'polkadot-api';
7
7
  * Core types for @parity/product-sdk
8
8
  */
9
9
 
10
- /** Bulletin configuration options */
11
- interface BulletinConfig {
12
- /** Bulletin environment to connect to */
13
- environment: BulletinEnvironment;
10
+ /** Cloud Storage configuration options */
11
+ interface CloudStorageConfig {
12
+ /** Cloud Storage environment to connect to */
13
+ environment: CloudStorageEnvironment;
14
14
  }
15
15
  /** Configuration for createApp */
16
16
  interface AppConfig {
@@ -19,11 +19,11 @@ interface AppConfig {
19
19
  /** Log level for SDK operations (default: 'info') */
20
20
  logLevel?: LogLevel;
21
21
  /**
22
- * Bulletin Chain configuration.
22
+ * Cloud Storage configuration.
23
23
  * - Omit or pass config object to enable (default: { environment: "paseo" })
24
- * - Pass `false` to disable bulletin initialization
24
+ * - Pass `false` to disable cloud storage initialization
25
25
  */
26
- bulletin?: BulletinConfig | false;
26
+ cloudStorage?: CloudStorageConfig | false;
27
27
  }
28
28
  /** Wallet API exposed by the SDK */
29
29
  interface WalletApi {
@@ -51,7 +51,7 @@ interface WalletApi {
51
51
  createProof(message: Uint8Array): Promise<Uint8Array>;
52
52
  }
53
53
  /** Storage API exposed by the SDK */
54
- interface StorageApi {
54
+ interface LocalStorageApi {
55
55
  /** Get a value by key */
56
56
  get(key: string): Promise<string | null>;
57
57
  /** Set a value by key */
@@ -107,10 +107,10 @@ interface ChainApi {
107
107
  */
108
108
  destroyAll(): void;
109
109
  }
110
- /** Bulletin Chain API exposed by the SDK */
111
- interface BulletinApi {
110
+ /** Cloud Storage API exposed by the SDK */
111
+ interface CloudStorageApi {
112
112
  /**
113
- * Upload data to Bulletin Chain.
113
+ * Upload data to the Cloud.
114
114
  *
115
115
  * Requires a wallet to be connected and an account selected. Throws
116
116
  * "No signer available …" otherwise.
@@ -129,12 +129,12 @@ interface BulletinApi {
129
129
  interface App {
130
130
  /** Wallet/signing operations */
131
131
  wallet: WalletApi;
132
- /** Key-value storage operations */
133
- storage: StorageApi;
132
+ /** Local Key-value storage operations */
133
+ localStorage: LocalStorageApi;
134
134
  /** Chain interaction operations */
135
135
  chain: ChainApi;
136
- /** Bulletin Chain operations (null if disabled via config) */
137
- bulletin: BulletinApi | null;
136
+ /** Cloud Storage operations (null if disabled via config) */
137
+ cloudStorage: CloudStorageApi | null;
138
138
  /** Get app configuration */
139
139
  getAppInfo(): AppConfig;
140
140
  }
@@ -148,4 +148,4 @@ interface Account {
148
148
  source: string;
149
149
  }
150
150
 
151
- export type { App as A, BulletinApi as B, ChainApi as C, StorageApi as S, WalletApi as W, Account as a, AppConfig as b, BulletinConfig as c };
151
+ export type { App as A, ChainApi as C, LocalStorageApi as L, WalletApi as W, Account as a, AppConfig as b, CloudStorageApi as c, CloudStorageConfig as d };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parity/product-sdk",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Unified SDK for building products in the Polkadot ecosystem - umbrella package",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -16,9 +16,9 @@
16
16
  "import": "./dist/address/index.js",
17
17
  "types": "./dist/address/index.d.ts"
18
18
  },
19
- "./bulletin": {
20
- "import": "./dist/bulletin/index.js",
21
- "types": "./dist/bulletin/index.d.ts"
19
+ "./cloud-storage": {
20
+ "import": "./dist/cloud-storage/index.js",
21
+ "types": "./dist/cloud-storage/index.d.ts"
22
22
  },
23
23
  "./chain": {
24
24
  "import": "./dist/chain/index.js",
@@ -48,9 +48,9 @@
48
48
  "import": "./dist/react/index.js",
49
49
  "types": "./dist/react/index.d.ts"
50
50
  },
51
- "./storage": {
52
- "import": "./dist/storage/index.js",
53
- "types": "./dist/storage/index.d.ts"
51
+ "./local-storage": {
52
+ "import": "./dist/local-storage/index.js",
53
+ "types": "./dist/local-storage/index.d.ts"
54
54
  },
55
55
  "./wallet": {
56
56
  "import": "./dist/wallet/index.js",
@@ -64,16 +64,16 @@
64
64
  "dependencies": {
65
65
  "polkadot-api": "^2.1.2",
66
66
  "@parity/product-sdk-address": "0.1.1",
67
- "@parity/product-sdk-chain-client": "0.4.2",
68
- "@parity/product-sdk-bulletin": "0.4.2",
67
+ "@parity/product-sdk-cloud-storage": "0.5.0",
68
+ "@parity/product-sdk-chain-client": "0.5.0",
69
+ "@parity/product-sdk-contracts": "0.6.0",
69
70
  "@parity/product-sdk-crypto": "0.1.1",
70
- "@parity/product-sdk-host": "0.4.0",
71
- "@parity/product-sdk-contracts": "0.5.1",
72
- "@parity/product-sdk-keys": "0.3.0",
71
+ "@parity/product-sdk-host": "0.5.0",
72
+ "@parity/product-sdk-keys": "0.3.1",
73
73
  "@parity/product-sdk-logger": "0.1.1",
74
- "@parity/product-sdk-signer": "0.3.0",
75
- "@parity/product-sdk-storage": "0.1.5",
76
- "@parity/product-sdk-tx": "0.2.4"
74
+ "@parity/product-sdk-signer": "0.4.0",
75
+ "@parity/product-sdk-tx": "0.2.5",
76
+ "@parity/product-sdk-local-storage": "0.2.0"
77
77
  },
78
78
  "peerDependencies": {
79
79
  "react": "^18.0.0 || ^19.0.0"
@@ -99,7 +99,7 @@
99
99
  ],
100
100
  "license": "Apache-2.0",
101
101
  "scripts": {
102
- "build": "tsup",
102
+ "build": "NODE_OPTIONS=--max-old-space-size=8192 tsup",
103
103
  "clean": "rm -rf dist"
104
104
  }
105
105
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @parity/product-sdk/bulletin
3
+ *
4
+ * Re-exports from @parity/product-sdk-cloud-storage.
5
+ */
6
+ export * from "@parity/product-sdk-cloud-storage";
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * createApp - Main entry point for the Product SDK
3
3
  *
4
- * Creates an App instance with wallet, storage, chain, and bulletin APIs.
4
+ * Creates an App instance with wallet, storage, chain, and cloud storage APIs.
5
5
  */
6
6
 
7
7
  import type { ChainDefinition } from "polkadot-api";
@@ -9,15 +9,19 @@ import type {
9
9
  App,
10
10
  AppConfig,
11
11
  WalletApi,
12
- StorageApi,
13
12
  ChainApi,
14
- BulletinApi,
15
13
  Account,
14
+ CloudStorageApi,
15
+ LocalStorageApi,
16
16
  } from "./types.js";
17
17
  import { configure, createLogger } from "@parity/product-sdk-logger";
18
- import { createKvStore } from "@parity/product-sdk-storage";
18
+ import { createLocalKvStore } from "@parity/product-sdk-local-storage";
19
19
  import { SignerManager } from "@parity/product-sdk-signer";
20
- import { BulletinClient, calculateCid, createLazySigner } from "@parity/product-sdk-bulletin";
20
+ import {
21
+ CloudStorageClient,
22
+ calculateCid,
23
+ createLazySigner,
24
+ } from "@parity/product-sdk-cloud-storage";
21
25
  import {
22
26
  createChainClient,
23
27
  getClient,
@@ -37,33 +41,33 @@ const log = createLogger("app");
37
41
  * ```ts
38
42
  * import { createApp } from '@parity/product-sdk';
39
43
  *
40
- * // Default: bulletin enabled with paseo environment
44
+ * // Default: cloud storage enabled with paseo environment
41
45
  * const app = await createApp({
42
46
  * name: 'my-app',
43
47
  * logLevel: 'info',
44
48
  * });
45
49
  *
46
- * // Custom bulletin environment
50
+ * // Custom cloud storage environment
47
51
  * const prodApp = await createApp({
48
52
  * name: 'my-app',
49
- * bulletin: { environment: 'polkadot' },
53
+ * cloudStorage: { environment: 'polkadot' },
50
54
  * });
51
55
  *
52
- * // Disable bulletin entirely
53
- * const noBulletinApp = await createApp({
56
+ * // Disable cloud storage entirely
57
+ * const noCloudStorageApp = await createApp({
54
58
  * name: 'my-app',
55
- * bulletin: false,
59
+ * cloudStorage: false,
56
60
  * });
57
61
  *
58
62
  * // Connect wallet
59
63
  * const { accounts } = await app.wallet.connect();
60
64
  *
61
65
  * // Use storage
62
- * await app.storage.set('key', 'value');
66
+ * await app.localStorage.set('key', 'value');
63
67
  *
64
- * // Use bulletin (check for null if it might be disabled)
65
- * if (app.bulletin) {
66
- * const cid = await app.bulletin.upload('hello world');
68
+ * // Use cloud storage (check for null if it might be disabled)
69
+ * if (app.cloudStorage) {
70
+ * const cid = await app.cloudStorage.upload('hello world');
67
71
  * }
68
72
  * ```
69
73
  */
@@ -76,44 +80,46 @@ export async function createApp(config: AppConfig): Promise<App> {
76
80
  log.info("Creating Product SDK app", { name: config.name });
77
81
 
78
82
  // Initialize storage (container-only - will throw if not in container)
79
- const kvStore = await createKvStore({ prefix: config.name });
83
+ const localKvStore = await createLocalKvStore({ prefix: config.name });
80
84
 
81
85
  // Initialize signer manager
82
86
  const signerManager = new SignerManager({
83
87
  dappName: config.name,
84
88
  });
85
89
 
86
- // Initialize bulletin client (configurable, defaults to paseo).
90
+ // Initialize cloud storage client (configurable, defaults to paseo).
87
91
  //
88
- // The signer is wrapped lazily so the bulletin client can be built before
92
+ // The signer is wrapped lazily so the cloud storage client can be built before
89
93
  // an account is selected. Uploads will throw a clear error if no signer
90
94
  // is available at submission time. Reads (fetch / fetchJson) don't need
91
95
  // a signer and work regardless.
92
- const bulletinEnabled = config.bulletin !== false;
93
- const bulletinEnvironment =
94
- typeof config.bulletin === "object" ? config.bulletin.environment : "paseo";
95
- const bulletinClient = bulletinEnabled
96
- ? await BulletinClient.create({
97
- environment: bulletinEnvironment,
96
+ const cloudStorageEnabled = config.cloudStorage !== false;
97
+ const cloudStorageEnvironment =
98
+ typeof config.cloudStorage === "object" ? config.cloudStorage.environment : "paseo";
99
+ const cloudStorageClient = cloudStorageEnabled
100
+ ? await CloudStorageClient.create({
101
+ environment: cloudStorageEnvironment,
98
102
  signer: createLazySigner(() => signerManager.getSigner()),
99
103
  })
100
104
  : null;
101
105
 
102
- if (bulletinEnabled) {
103
- log.debug("Bulletin client initialized", { environment: bulletinEnvironment });
106
+ if (cloudStorageEnabled) {
107
+ log.debug("Cloud Storage client (Bulletin) initialized", {
108
+ environment: cloudStorageEnvironment,
109
+ });
104
110
  } else {
105
- log.debug("Bulletin client disabled");
111
+ log.debug("Cloud Storage client disabled");
106
112
  }
107
113
 
108
114
  // Create storage API adapter
109
- const storageApi: StorageApi = {
110
- get: (key) => kvStore.get(key),
111
- set: (key, value) => kvStore.set(key, value),
112
- getJSON: <T>(key: string) => kvStore.getJSON<T>(key),
113
- setJSON: <T>(key: string, value: T) => kvStore.setJSON(key, value),
114
- remove: (key) => kvStore.remove(key),
115
+ const localStorageApi: LocalStorageApi = {
116
+ get: (key) => localKvStore.get(key),
117
+ set: (key, value) => localKvStore.set(key, value),
118
+ getJSON: <T>(key: string) => localKvStore.getJSON<T>(key),
119
+ setJSON: <T>(key: string, value: T) => localKvStore.setJSON(key, value),
120
+ remove: (key) => localKvStore.remove(key),
115
121
  clear: async () => {
116
- // KvStore doesn't have clear - this is a no-op
122
+ // LocalKvStore doesn't have clear - this is a no-op
117
123
  log.debug("clear() is not supported in container storage mode");
118
124
  },
119
125
  };
@@ -153,27 +159,27 @@ export async function createApp(config: AppConfig): Promise<App> {
153
159
  },
154
160
  };
155
161
 
156
- // Create bulletin API adapter (null if disabled)
157
- const bulletinApi: BulletinApi | null = bulletinClient
162
+ // Create Cloud Storage API adapter (null if disabled)
163
+ const cloudStorageApi: CloudStorageApi | null = cloudStorageClient
158
164
  ? {
159
165
  upload: async (data) => {
160
166
  const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
161
167
  // Explicitly request a DAG-PB manifest so chunked uploads always
162
168
  // resolve to a single root CID. Without this, AsyncBulletinClient
163
169
  // can return `result.cid: undefined` for chunked-without-manifest
164
- // uploads — but BulletinApi.upload promises a string return, and
170
+ // uploads — but CloudStorageApi.upload promises a string return, and
165
171
  // app consumers expect a CID they can hand to `fetch(cid)`. Keep
166
172
  // the defensive null-check below as belt-and-braces in case the
167
173
  // upstream contract shifts.
168
- const result = await bulletinClient.store(bytes).withManifest(true).send();
174
+ const result = await cloudStorageClient.store(bytes).withManifest(true).send();
169
175
  if (!result.cid) {
170
176
  throw new Error(
171
- "Bulletin upload returned no CID despite .withManifest(true). Upstream contract may have shifted — file an issue.",
177
+ "Cloud storage upload returned no CID despite .withManifest(true). Upstream contract may have shifted — file an issue.",
172
178
  );
173
179
  }
174
180
  return result.cid.toString();
175
181
  },
176
- fetch: (cid) => bulletinClient.fetchBytes(cid),
182
+ fetch: (cid) => cloudStorageClient.fetchBytes(cid),
177
183
  computeCid: async (data) => {
178
184
  const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
179
185
  const cid = await calculateCid(bytes);
@@ -184,14 +190,14 @@ export async function createApp(config: AppConfig): Promise<App> {
184
190
 
185
191
  log.info("Product SDK app created", {
186
192
  name: config.name,
187
- bulletin: bulletinEnabled ? bulletinEnvironment : "disabled",
193
+ cloudStorage: cloudStorageEnabled ? cloudStorageEnvironment : "disabled",
188
194
  });
189
195
 
190
196
  return {
191
197
  wallet: walletApi,
192
- storage: storageApi,
198
+ localStorage: localStorageApi,
193
199
  chain: chainApi,
194
- bulletin: bulletinApi,
200
+ cloudStorage: cloudStorageApi,
195
201
  getAppInfo: () => ({ ...config }),
196
202
  };
197
203
  }
package/src/core/types.ts CHANGED
@@ -3,17 +3,17 @@
3
3
  */
4
4
 
5
5
  import type { LogLevel } from "@parity/product-sdk-logger";
6
- import type { BulletinEnvironment } from "@parity/product-sdk-bulletin";
6
+ import type { CloudStorageEnvironment } from "@parity/product-sdk-cloud-storage";
7
7
  import type { ChainClient } from "@parity/product-sdk-chain-client";
8
8
  import type { ChainDefinition, TypedApi, PolkadotClient } from "polkadot-api";
9
9
 
10
10
  export type { LogLevel };
11
11
  export type { ChainClient };
12
12
 
13
- /** Bulletin configuration options */
14
- export interface BulletinConfig {
15
- /** Bulletin environment to connect to */
16
- environment: BulletinEnvironment;
13
+ /** Cloud Storage configuration options */
14
+ export interface CloudStorageConfig {
15
+ /** Cloud Storage environment to connect to */
16
+ environment: CloudStorageEnvironment;
17
17
  }
18
18
 
19
19
  /** Configuration for createApp */
@@ -23,11 +23,11 @@ export interface AppConfig {
23
23
  /** Log level for SDK operations (default: 'info') */
24
24
  logLevel?: LogLevel;
25
25
  /**
26
- * Bulletin Chain configuration.
26
+ * Cloud Storage configuration.
27
27
  * - Omit or pass config object to enable (default: { environment: "paseo" })
28
- * - Pass `false` to disable bulletin initialization
28
+ * - Pass `false` to disable cloud storage initialization
29
29
  */
30
- bulletin?: BulletinConfig | false;
30
+ cloudStorage?: CloudStorageConfig | false;
31
31
  }
32
32
 
33
33
  /** Wallet API exposed by the SDK */
@@ -55,7 +55,7 @@ export interface WalletApi {
55
55
  }
56
56
 
57
57
  /** Storage API exposed by the SDK */
58
- export interface StorageApi {
58
+ export interface LocalStorageApi {
59
59
  /** Get a value by key */
60
60
  get(key: string): Promise<string | null>;
61
61
  /** Set a value by key */
@@ -117,10 +117,10 @@ export interface ChainApi {
117
117
  destroyAll(): void;
118
118
  }
119
119
 
120
- /** Bulletin Chain API exposed by the SDK */
121
- export interface BulletinApi {
120
+ /** Cloud Storage API exposed by the SDK */
121
+ export interface CloudStorageApi {
122
122
  /**
123
- * Upload data to Bulletin Chain.
123
+ * Upload data to the Cloud.
124
124
  *
125
125
  * Requires a wallet to be connected and an account selected. Throws
126
126
  * "No signer available …" otherwise.
@@ -140,12 +140,12 @@ export interface BulletinApi {
140
140
  export interface App {
141
141
  /** Wallet/signing operations */
142
142
  wallet: WalletApi;
143
- /** Key-value storage operations */
144
- storage: StorageApi;
143
+ /** Local Key-value storage operations */
144
+ localStorage: LocalStorageApi;
145
145
  /** Chain interaction operations */
146
146
  chain: ChainApi;
147
- /** Bulletin Chain operations (null if disabled via config) */
148
- bulletin: BulletinApi | null;
147
+ /** Cloud Storage operations (null if disabled via config) */
148
+ cloudStorage: CloudStorageApi | null;
149
149
  /** Get app configuration */
150
150
  getAppInfo(): AppConfig;
151
151
  }
package/src/index.ts CHANGED
@@ -16,7 +16,7 @@
16
16
  * const { accounts } = await app.wallet.connect();
17
17
  *
18
18
  * // Use storage
19
- * await app.storage.set('key', 'value');
19
+ * await app.localStorage.set('key', 'value');
20
20
  * ```
21
21
  *
22
22
  * @packageDocumentation
@@ -30,9 +30,9 @@ export type {
30
30
  AppConfig,
31
31
  LogLevel,
32
32
  WalletApi,
33
- StorageApi,
33
+ LocalStorageApi,
34
34
  ChainApi,
35
- BulletinApi,
35
+ CloudStorageApi,
36
36
  Account,
37
37
  ChainClient,
38
38
  ChainDefinition,
@@ -45,5 +45,5 @@ export type { LogEntry, LogHandler, LoggerConfig, Logger } from "./core/logger.j
45
45
  export { isInsideContainer, isInsideContainerSync } from "@parity/product-sdk-host";
46
46
  export { createChainClient } from "@parity/product-sdk-chain-client";
47
47
  export { SignerManager } from "@parity/product-sdk-signer";
48
- export { createKvStore } from "@parity/product-sdk-storage";
49
- export { BulletinClient, calculateCid } from "@parity/product-sdk-bulletin";
48
+ export { createLocalKvStore } from "@parity/product-sdk-local-storage";
49
+ export { CloudStorageClient, calculateCid } from "@parity/product-sdk-cloud-storage";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @parity/product-sdk/local-storage
3
+ *
4
+ * Re-exports from @parity/product-sdk-local-storage.
5
+ */
6
+ export * from "@parity/product-sdk-local-storage";
@@ -17,7 +17,7 @@ export const ProductSDKContext = createContext<App | null>(null);
17
17
  * ```tsx
18
18
  * function MyComponent() {
19
19
  * const app = useProductSDK();
20
- * // Use app.wallet, app.storage, etc.
20
+ * // Use app.wallet, app.localStorage, etc.
21
21
  * }
22
22
  * ```
23
23
  */
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @example
8
8
  * ```tsx
9
- * import { ProductSDKProvider, useWallet, useStorage } from '@parity/product-sdk/react';
9
+ * import { ProductSDKProvider, useWallet, useLocalStorage } from '@parity/product-sdk/react';
10
10
  *
11
11
  * function App() {
12
12
  * return (
@@ -18,7 +18,7 @@
18
18
  *
19
19
  * function MyApp() {
20
20
  * const { isConnected, connect, accounts } = useWallet();
21
- * const [theme, setTheme] = useStorage('theme', 'light');
21
+ * const [theme, setTheme] = useLocalStorage('theme', 'light');
22
22
  *
23
23
  * // ...
24
24
  * }
@@ -36,6 +36,6 @@ export { ProductSDKContext, useProductSDK } from "./context.js";
36
36
  export { useWallet } from "./useWallet.js";
37
37
  export type { UseWalletState, UseWalletActions, UseWalletReturn } from "./useWallet.js";
38
38
 
39
- export { useStorage, useStorageString } from "./useStorage.js";
39
+ export { useLocalStorage, useLocalStorageString } from "./useLocalStorage.js";
40
40
 
41
41
  export { useChain } from "./useChain.js";
@@ -1,5 +1,5 @@
1
1
  /**
2
- * useStorage hook
2
+ * useLocalStorage hook
3
3
  */
4
4
 
5
5
  import { useState, useEffect, useCallback } from "react";
@@ -14,7 +14,7 @@ import { useProductSDK } from "./context.js";
14
14
  * @example
15
15
  * ```tsx
16
16
  * function ThemeToggle() {
17
- * const [theme, setTheme, { loading }] = useStorage('theme', 'light');
17
+ * const [theme, setTheme, { loading }] = useLocalStorage('theme', 'light');
18
18
  *
19
19
  * if (loading) return <div>Loading...</div>;
20
20
  *
@@ -26,7 +26,7 @@ import { useProductSDK } from "./context.js";
26
26
  * }
27
27
  * ```
28
28
  */
29
- export function useStorage<T = string>(
29
+ export function useLocalStorage<T = string>(
30
30
  key: string,
31
31
  defaultValue?: T,
32
32
  ): [T | null, (value: T) => Promise<void>, { loading: boolean; error: Error | null }] {
@@ -43,7 +43,7 @@ export function useStorage<T = string>(
43
43
  const loadValue = async () => {
44
44
  try {
45
45
  setLoading(true);
46
- const stored = await app.storage.getJSON<T>(key);
46
+ const stored = await app.localStorage.getJSON<T>(key);
47
47
  if (mounted) {
48
48
  setValue(stored ?? defaultValue ?? null);
49
49
  setLoading(false);
@@ -67,7 +67,7 @@ export function useStorage<T = string>(
67
67
  async (newValue: T) => {
68
68
  try {
69
69
  setError(null);
70
- await app.storage.setJSON(key, newValue);
70
+ await app.localStorage.setJSON(key, newValue);
71
71
  setValue(newValue);
72
72
  } catch (e) {
73
73
  setError(e instanceof Error ? e : new Error(String(e)));
@@ -86,7 +86,7 @@ export function useStorage<T = string>(
86
86
  * @param key - Storage key
87
87
  * @param defaultValue - Default value
88
88
  */
89
- export function useStorageString(
89
+ export function useLocalStorageString(
90
90
  key: string,
91
91
  defaultValue?: string,
92
92
  ): [string | null, (value: string) => Promise<void>, { loading: boolean }] {
@@ -99,7 +99,7 @@ export function useStorageString(
99
99
  let mounted = true;
100
100
 
101
101
  const loadValue = async () => {
102
- const stored = await app.storage.get(key);
102
+ const stored = await app.localStorage.get(key);
103
103
  if (mounted) {
104
104
  setValue(stored ?? defaultValue ?? null);
105
105
  setLoading(false);
@@ -115,7 +115,7 @@ export function useStorageString(
115
115
 
116
116
  const setStoredValue = useCallback(
117
117
  async (newValue: string) => {
118
- await app.storage.set(key, newValue);
118
+ await app.localStorage.set(key, newValue);
119
119
  setValue(newValue);
120
120
  },
121
121
  [app, key],
@@ -1 +0,0 @@
1
- export * from '@parity/product-sdk-bulletin';
@@ -1,3 +0,0 @@
1
- export * from '@parity/product-sdk-bulletin';
2
- //# sourceMappingURL=index.js.map
3
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/createApp.ts"],"names":[],"mappings":"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","file":"chunk-6W3TCR3W.js","sourcesContent":["/**\n * createApp - Main entry point for the Product SDK\n *\n * Creates an App instance with wallet, storage, chain, and bulletin APIs.\n */\n\nimport type { ChainDefinition } from \"polkadot-api\";\nimport type {\n App,\n AppConfig,\n WalletApi,\n StorageApi,\n ChainApi,\n BulletinApi,\n Account,\n} from \"./types.js\";\nimport { configure, createLogger } from \"@parity/product-sdk-logger\";\nimport { createKvStore } from \"@parity/product-sdk-storage\";\nimport { SignerManager } from \"@parity/product-sdk-signer\";\nimport { BulletinClient, calculateCid, createLazySigner } from \"@parity/product-sdk-bulletin\";\nimport {\n createChainClient,\n getClient,\n isConnected,\n destroyAll,\n} from \"@parity/product-sdk-chain-client\";\n\nconst log = createLogger(\"app\");\n\n/**\n * Create a new Product SDK app instance\n *\n * @param config - Application configuration\n * @returns App instance with all APIs\n *\n * @example\n * ```ts\n * import { createApp } from '@parity/product-sdk';\n *\n * // Default: bulletin enabled with paseo environment\n * const app = await createApp({\n * name: 'my-app',\n * logLevel: 'info',\n * });\n *\n * // Custom bulletin environment\n * const prodApp = await createApp({\n * name: 'my-app',\n * bulletin: { environment: 'polkadot' },\n * });\n *\n * // Disable bulletin entirely\n * const noBulletinApp = await createApp({\n * name: 'my-app',\n * bulletin: false,\n * });\n *\n * // Connect wallet\n * const { accounts } = await app.wallet.connect();\n *\n * // Use storage\n * await app.storage.set('key', 'value');\n *\n * // Use bulletin (check for null if it might be disabled)\n * if (app.bulletin) {\n * const cid = await app.bulletin.upload('hello world');\n * }\n * ```\n */\nexport async function createApp(config: AppConfig): Promise<App> {\n // Set log level if specified\n if (config.logLevel) {\n configure({ level: config.logLevel });\n }\n\n log.info(\"Creating Product SDK app\", { name: config.name });\n\n // Initialize storage (container-only - will throw if not in container)\n const kvStore = await createKvStore({ prefix: config.name });\n\n // Initialize signer manager\n const signerManager = new SignerManager({\n dappName: config.name,\n });\n\n // Initialize bulletin client (configurable, defaults to paseo).\n //\n // The signer is wrapped lazily so the bulletin client can be built before\n // an account is selected. Uploads will throw a clear error if no signer\n // is available at submission time. Reads (fetch / fetchJson) don't need\n // a signer and work regardless.\n const bulletinEnabled = config.bulletin !== false;\n const bulletinEnvironment =\n typeof config.bulletin === \"object\" ? config.bulletin.environment : \"paseo\";\n const bulletinClient = bulletinEnabled\n ? await BulletinClient.create({\n environment: bulletinEnvironment,\n signer: createLazySigner(() => signerManager.getSigner()),\n })\n : null;\n\n if (bulletinEnabled) {\n log.debug(\"Bulletin client initialized\", { environment: bulletinEnvironment });\n } else {\n log.debug(\"Bulletin client disabled\");\n }\n\n // Create storage API adapter\n const storageApi: StorageApi = {\n get: (key) => kvStore.get(key),\n set: (key, value) => kvStore.set(key, value),\n getJSON: <T>(key: string) => kvStore.getJSON<T>(key),\n setJSON: <T>(key: string, value: T) => kvStore.setJSON(key, value),\n remove: (key) => kvStore.remove(key),\n clear: async () => {\n // KvStore doesn't have clear - this is a no-op\n log.debug(\"clear() is not supported in container storage mode\");\n },\n };\n\n // Create wallet API adapter\n const walletApi = createWalletApi(signerManager);\n\n // Create chain API\n const chainApi: ChainApi = {\n getClient(descriptor) {\n log.debug(\"getClient called\", { genesis: descriptor.genesis });\n const client = getClient(descriptor);\n return client.getTypedApi(descriptor);\n },\n\n getRawClient(descriptor) {\n log.debug(\"getRawClient called\", { genesis: descriptor.genesis });\n return getClient(descriptor);\n },\n\n async connect<T extends Record<string, ChainDefinition>>(chains: T) {\n log.debug(\"connect called\", { chains: Object.keys(chains) });\n // Build empty rpcs object (required by API but unused - host routes connections)\n const rpcs = Object.fromEntries(\n Object.keys(chains).map((k) => [k, [] as readonly string[]]),\n ) as { [K in keyof T]: readonly string[] };\n return createChainClient({ chains, rpcs });\n },\n\n isConnected(descriptor) {\n return isConnected(descriptor);\n },\n\n destroyAll() {\n log.debug(\"destroyAll called\");\n destroyAll();\n },\n };\n\n // Create bulletin API adapter (null if disabled)\n const bulletinApi: BulletinApi | null = bulletinClient\n ? {\n upload: async (data) => {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n // Explicitly request a DAG-PB manifest so chunked uploads always\n // resolve to a single root CID. Without this, AsyncBulletinClient\n // can return `result.cid: undefined` for chunked-without-manifest\n // uploads — but BulletinApi.upload promises a string return, and\n // app consumers expect a CID they can hand to `fetch(cid)`. Keep\n // the defensive null-check below as belt-and-braces in case the\n // upstream contract shifts.\n const result = await bulletinClient.store(bytes).withManifest(true).send();\n if (!result.cid) {\n throw new Error(\n \"Bulletin upload returned no CID despite .withManifest(true). Upstream contract may have shifted — file an issue.\",\n );\n }\n return result.cid.toString();\n },\n fetch: (cid) => bulletinClient.fetchBytes(cid),\n computeCid: async (data) => {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n const cid = await calculateCid(bytes);\n return cid.toString();\n },\n }\n : null;\n\n log.info(\"Product SDK app created\", {\n name: config.name,\n bulletin: bulletinEnabled ? bulletinEnvironment : \"disabled\",\n });\n\n return {\n wallet: walletApi,\n storage: storageApi,\n chain: chainApi,\n bulletin: bulletinApi,\n getAppInfo: () => ({ ...config }),\n };\n}\n\n/**\n * Create wallet API adapter using SignerManager from leaf package\n */\nfunction createWalletApi(signerManager: SignerManager): WalletApi {\n // Track account change subscribers\n const accountChangeSubscribers = new Set<(account: Account | null) => void>();\n\n // Subscribe to signer manager state changes\n signerManager.subscribe((state) => {\n const account = state.selectedAccount\n ? {\n address: state.selectedAccount.address,\n name: state.selectedAccount.name ?? undefined,\n source: state.selectedAccount.source,\n }\n : null;\n for (const callback of accountChangeSubscribers) {\n try {\n callback(account);\n } catch (e) {\n log.warn(\"Account change callback threw\", { error: e });\n }\n }\n });\n\n return {\n async connect(): Promise<{ accounts: Account[] }> {\n const result = await signerManager.connect();\n if (!result.ok) {\n throw new Error(result.error.message);\n }\n return {\n accounts: result.value.map((a) => ({\n address: a.address,\n name: a.name ?? undefined,\n source: a.source,\n })),\n };\n },\n\n async disconnect(): Promise<void> {\n signerManager.disconnect();\n },\n\n getAccounts(): Account[] {\n return signerManager.getState().accounts.map((a) => ({\n address: a.address,\n name: a.name ?? undefined,\n source: a.source,\n }));\n },\n\n getSelectedAccount(): Account | null {\n const selected = signerManager.getState().selectedAccount;\n if (!selected) return null;\n return {\n address: selected.address,\n name: selected.name ?? undefined,\n source: selected.source,\n };\n },\n\n selectAccount(address: string): void {\n signerManager.selectAccount(address);\n },\n\n async signMessage(message: string | Uint8Array): Promise<Uint8Array> {\n const bytes = typeof message === \"string\" ? new TextEncoder().encode(message) : message;\n const result = await signerManager.signRaw(bytes);\n if (!result.ok) {\n throw new Error(result.error.message);\n }\n return result.value;\n },\n\n onAccountChange(callback: (account: Account | null) => void): () => void {\n accountChangeSubscribers.add(callback);\n return () => accountChangeSubscribers.delete(callback);\n },\n\n getProductAccount(): Account | null {\n // Product accounts require async call - this sync API can't support it properly\n // Users should use SignerManager.getProductAccount() directly\n log.warn(\n \"getProductAccount() is deprecated - use SignerManager.getProductAccount() directly\",\n );\n return null;\n },\n\n getAnonymousAlias(): string | null {\n // Anonymous aliases require async call - this sync API can't support it properly\n // Users should use SignerManager.getProductAccountAlias() directly\n log.warn(\n \"getAnonymousAlias() is deprecated - use SignerManager.getProductAccountAlias() directly\",\n );\n return null;\n },\n\n async createProof(_message: Uint8Array): Promise<Uint8Array> {\n // Ring VRF proofs require SignerManager.createRingVRFProof() directly\n throw new Error(\n \"createProof() is not implemented in the App API. \" +\n \"Use SignerManager.createRingVRFProof() directly.\",\n );\n },\n };\n}\n"]}
@@ -1 +0,0 @@
1
- export * from '@parity/product-sdk-storage';
@@ -1,3 +0,0 @@
1
- export * from '@parity/product-sdk-storage';
2
- //# sourceMappingURL=index.js.map
3
- //# sourceMappingURL=index.js.map
@@ -1,6 +0,0 @@
1
- /**
2
- * @parity/product-sdk/bulletin
3
- *
4
- * Re-exports from @parity/product-sdk-bulletin.
5
- */
6
- export * from "@parity/product-sdk-bulletin";
@@ -1,6 +0,0 @@
1
- /**
2
- * @parity/product-sdk/storage
3
- *
4
- * Re-exports from @parity/product-sdk-storage.
5
- */
6
- export * from "@parity/product-sdk-storage";
File without changes
File without changes