@parity/product-sdk 0.6.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/address/index.d.ts +2 -2
- package/dist/{chunk-6W3TCR3W.js → chunk-JC4RBXLY.js} +27 -25
- package/dist/chunk-JC4RBXLY.js.map +1 -0
- package/dist/chunk-JVJ552RU.js +3 -0
- package/dist/{chunk-XSKBA5SR.js.map → chunk-JVJ552RU.js.map} +1 -1
- package/dist/cloud-storage/index.d.ts +1 -0
- package/dist/cloud-storage/index.js +3 -0
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +2 -2
- package/dist/identity/index.js.map +1 -1
- package/dist/index.d.ts +15 -15
- package/dist/index.js +4 -4
- package/dist/local-storage/index.d.ts +1 -0
- package/dist/local-storage/index.js +3 -0
- package/dist/react/index.d.ts +8 -8
- package/dist/react/index.js +8 -8
- package/dist/react/index.js.map +1 -1
- package/dist/{types-DVpAr2JN.d.ts → types-AjDV1BTd.d.ts} +17 -17
- package/package.json +16 -16
- package/src/address/index.ts +2 -0
- package/src/chain/index.ts +2 -0
- package/src/cloud-storage/index.ts +8 -0
- package/src/contracts/index.ts +2 -0
- package/src/core/createApp.ts +51 -43
- package/src/core/index.ts +2 -0
- package/src/core/logger.ts +2 -0
- package/src/core/types.ts +18 -16
- package/src/crypto/index.ts +2 -0
- package/src/host/index.ts +2 -0
- package/src/identity/dotns.ts +2 -0
- package/src/identity/index.ts +2 -0
- package/src/identity/product-account.ts +2 -0
- package/src/identity/types.ts +2 -0
- package/src/index.ts +7 -5
- package/src/local-storage/index.ts +8 -0
- package/src/react/context.ts +3 -1
- package/src/react/index.ts +5 -3
- package/src/react/provider.tsx +2 -0
- package/src/react/useChain.ts +2 -0
- package/src/react/{useStorage.ts → useLocalStorage.ts} +10 -8
- package/src/react/useWallet.ts +2 -0
- package/src/wallet/index.ts +2 -0
- package/dist/bulletin/index.d.ts +0 -1
- package/dist/bulletin/index.js +0 -3
- package/dist/chunk-6W3TCR3W.js.map +0 -1
- package/dist/chunk-XSKBA5SR.js +0 -3
- package/dist/storage/index.d.ts +0 -1
- package/dist/storage/index.js +0 -3
- package/src/bulletin/index.ts +0 -6
- package/src/storage/index.ts +0 -6
- /package/dist/{bulletin → cloud-storage}/index.js.map +0 -0
- /package/dist/{storage → local-storage}/index.js.map +0 -0
package/dist/address/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export * from '@parity/product-sdk-address';
|
|
2
|
-
import '@parity/product-sdk-
|
|
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 {
|
|
2
|
+
import { createLocalKvStore } from '@parity/product-sdk-local-storage';
|
|
3
3
|
import { SignerManager } from '@parity/product-sdk-signer';
|
|
4
|
-
import {
|
|
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
|
|
14
|
+
const localKvStore = await createLocalKvStore({ prefix: config.name });
|
|
15
15
|
const signerManager = new SignerManager({
|
|
16
16
|
dappName: config.name
|
|
17
17
|
});
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
environment:
|
|
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 (
|
|
25
|
-
log.debug("
|
|
24
|
+
if (cloudStorageEnabled) {
|
|
25
|
+
log.debug("Cloud Storage client (Bulletin) initialized", {
|
|
26
|
+
environment: cloudStorageEnvironment
|
|
27
|
+
});
|
|
26
28
|
} else {
|
|
27
|
-
log.debug("
|
|
29
|
+
log.debug("Cloud Storage client disabled");
|
|
28
30
|
}
|
|
29
|
-
const
|
|
30
|
-
get: (key) =>
|
|
31
|
-
set: (key, value) =>
|
|
32
|
-
getJSON: (key) =>
|
|
33
|
-
setJSON: (key, value) =>
|
|
34
|
-
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
|
|
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
|
|
70
|
+
const result = await cloudStorageClient.store(bytes).withManifest(true).send();
|
|
69
71
|
if (!result.cid) {
|
|
70
72
|
throw new Error(
|
|
71
|
-
"
|
|
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) =>
|
|
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
|
-
|
|
87
|
+
cloudStorage: cloudStorageEnabled ? cloudStorageEnvironment : "disabled"
|
|
86
88
|
});
|
|
87
89
|
return {
|
|
88
90
|
wallet: walletApi,
|
|
89
|
-
|
|
91
|
+
localStorage: localStorageApi,
|
|
90
92
|
chain: chainApi,
|
|
91
|
-
|
|
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-
|
|
181
|
-
//# sourceMappingURL=chunk-
|
|
182
|
+
//# sourceMappingURL=chunk-JC4RBXLY.js.map
|
|
183
|
+
//# sourceMappingURL=chunk-JC4RBXLY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/createApp.ts"],"names":[],"mappings":"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","file":"chunk-JC4RBXLY.js","sourcesContent":["// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\n/**\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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-JVJ552RU.js","sourcesContent":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@parity/product-sdk-cloud-storage';
|
package/dist/core/index.d.ts
CHANGED
|
@@ -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,
|
|
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-
|
|
8
|
+
import '@parity/product-sdk-local-storage';
|
|
9
|
+
import '@parity/product-sdk-cloud-storage';
|
package/dist/core/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { configure, createLogger } from '../chunk-
|
|
2
|
-
export { createApp } from '../chunk-
|
|
1
|
+
export { configure, createLogger } from '../chunk-JVJ552RU.js';
|
|
2
|
+
export { createApp } from '../chunk-JC4RBXLY.js';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/identity/dotns.ts","../../src/identity/product-account.ts"],"names":["log","createLogger"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * DotNS (Polkadot Name Service) utilities\n *\n * Provides name resolution for .dot domains\n */\n\nimport { createLogger } from \"@parity/product-sdk-logger\";\nimport type { DotNsRecord } from \"./types.js\";\n\nconst log = createLogger(\"identity\");\n\n/**\n * Check if a string is a valid DotNS name\n *\n * @param name - Name to validate\n * @returns True if valid DotNS name\n */\nexport function isValidDotNsName(name: string): boolean {\n // Basic validation: alphanumeric, hyphens, ends with .dot\n if (!name.endsWith(\".dot\")) return false;\n const label = name.slice(0, -4);\n if (label.length < 3 || label.length > 63) return false;\n return /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(label);\n}\n\n/**\n * Normalize a DotNS name (lowercase, trim whitespace)\n *\n * @param name - Name to normalize\n * @returns Normalized name\n */\nexport function normalizeDotNsName(name: string): string {\n let normalized = name.toLowerCase().trim();\n if (!normalized.endsWith(\".dot\")) {\n normalized += \".dot\";\n }\n return normalized;\n}\n\n/**\n * Resolve a DotNS name to an address\n *\n * @param name - DotNS name (e.g., \"alice.dot\")\n * @returns Resolved record or null if not found\n *\n * @example\n * ```ts\n * const record = await resolveDotNs('alice.dot');\n * if (record) {\n * console.log('Address:', record.address);\n * }\n * ```\n */\nexport async function resolveDotNs(name: string): Promise<DotNsRecord | null> {\n const normalized = normalizeDotNsName(name);\n\n if (!isValidDotNsName(normalized)) {\n log.warn(\"Invalid DotNS name\", { name });\n return null;\n }\n\n log.debug(\"Resolving DotNS name\", { name: normalized });\n\n // TODO: Implement via PAPI query to DotNS pallet\n throw new Error(\n \"resolveDotNs() is not yet implemented. \" +\n \"This is a skeleton for the Product SDK structure.\",\n );\n}\n\n/**\n * Reverse resolve an address to a DotNS name\n *\n * @param address - SS58 address\n * @returns Primary name or null if none set\n */\nexport async function reverseDotNs(address: string): Promise<string | null> {\n log.debug(\"Reverse resolving address\", { address });\n\n // TODO: Implement via PAPI query to DotNS pallet\n throw new Error(\n \"reverseDotNs() is not yet implemented. \" +\n \"This is a skeleton for the Product SDK structure.\",\n );\n}\n\n/**\n * Check if a DotNS name is available for registration\n *\n * @param name - Name to check\n * @returns True if available\n */\nexport async function isDotNsAvailable(name: string): Promise<boolean> {\n const record = await resolveDotNs(name).catch(() => null);\n return record === null;\n}\n","/**\n * Context alias derivation\n *\n * Derives a deterministic, context-bound alias from a parent account using blake2b-256.\n *\n * NOTE: this is NOT the canonical sr25519 product-account derivation used by\n * mobile, desktop, and dotli hosts. For that, use\n * `@parity/product-sdk-keys::deriveProductAccountPublicKey`.\n */\n\nimport { createLogger } from \"@parity/product-sdk-logger\";\nimport { blake2b256 } from \"@parity/product-sdk-crypto\";\nimport { ss58Encode, ss58Decode, deriveH160 } from \"@parity/product-sdk-address\";\nimport type { ContextAliasInfo, AnonymousAliasInfo, RingLocation } from \"./types.js\";\n\nconst log = createLogger(\"identity\");\n\n/**\n * Derive a context-bound alias from a parent account.\n *\n * The alias is deterministically derived using:\n * aliasPublicKey = blake2b256(parentPublicKey || context)\n *\n * @param parentAddress - Parent account SS58 address\n * @param context - Context string for derivation (e.g. an app id or scope label)\n * @param ss58Prefix - SS58 prefix (default: 42)\n * @returns Context alias info\n *\n * @example\n * ```ts\n * const alias = deriveContextAlias(\n * '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',\n * 'voting-round-1'\n * );\n * console.log('Alias address:', alias.address);\n * ```\n */\nexport function deriveContextAlias(\n parentAddress: string,\n context: string,\n ss58Prefix = 42,\n): ContextAliasInfo {\n const { publicKey: parentPublicKey } = ss58Decode(parentAddress);\n\n // Derive alias public key: blake2b-256(parentPublicKey || context)\n const contextBytes = new TextEncoder().encode(context);\n const combined = new Uint8Array(parentPublicKey.length + contextBytes.length);\n combined.set(parentPublicKey, 0);\n combined.set(contextBytes, parentPublicKey.length);\n\n const aliasPublicKey = blake2b256(combined);\n const address = ss58Encode(aliasPublicKey, ss58Prefix);\n const h160Address = deriveH160(aliasPublicKey);\n\n log.debug(\"Derived context alias\", {\n parentAddress,\n context,\n address,\n });\n\n return {\n address,\n h160Address,\n parentAddress,\n context,\n };\n}\n\n/**\n * Verify that a context alias was derived from a parent account.\n *\n * @param aliasAddress - Context alias SS58 address\n * @param parentAddress - Claimed parent address\n * @param context - Context string used for derivation\n * @returns True if derivation is valid\n */\nexport function verifyContextAlias(\n aliasAddress: string,\n parentAddress: string,\n context: string,\n): boolean {\n try {\n const derived = deriveContextAlias(parentAddress, context);\n const { publicKey: aliasKey } = ss58Decode(aliasAddress);\n const { publicKey: derivedKey } = ss58Decode(derived.address);\n\n // Compare public keys\n if (aliasKey.length !== derivedKey.length) return false;\n for (let i = 0; i < aliasKey.length; i++) {\n if (aliasKey[i] !== derivedKey[i]) return false;\n }\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Derive an anonymous alias using Ring VRF\n *\n * This creates a context-specific alias that cannot be linked\n * back to the original identity without the ring proof.\n *\n * @param context - Context for alias derivation (e.g., \"voting-round-1\")\n * @param ringLocation - Ring location for proof generation\n * @returns Anonymous alias info\n */\nexport function deriveAnonymousAlias(\n context: string,\n ringLocation: RingLocation,\n): AnonymousAliasInfo {\n log.debug(\"Deriving anonymous alias\", { context, ringLocation });\n\n // TODO: Implement Ring VRF alias derivation\n // This requires the Ring VRF implementation from TruAPI\n throw new Error(\n \"deriveAnonymousAlias() is not yet implemented. \" +\n \"This requires container mode with Ring VRF support.\",\n );\n}\n\n/**\n * Create a Ring VRF proof for a message\n *\n * @param message - Message to prove\n * @param ringLocation - Ring location\n * @returns Proof bytes\n */\nexport async function createRingProof(\n message: Uint8Array,\n ringLocation: RingLocation,\n): Promise<Uint8Array> {\n log.debug(\"Creating ring proof\", { ringLocation });\n\n // TODO: Implement Ring VRF proof creation via TruAPI\n throw new Error(\n \"createRingProof() is not yet implemented. \" +\n \"This requires container mode with Ring VRF support.\",\n );\n}\n\n/**\n * Verify a Ring VRF proof\n *\n * @param message - Original message\n * @param proof - Proof bytes\n * @param alias - Expected alias\n * @returns True if proof is valid\n */\nexport async function verifyRingProof(\n message: Uint8Array,\n proof: Uint8Array,\n alias: string,\n): Promise<boolean> {\n log.debug(\"Verifying ring proof\");\n\n // TODO: Implement Ring VRF proof verification\n throw new Error(\n \"verifyRingProof() is not yet implemented. \" +\n \"This requires container mode with Ring VRF support.\",\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/identity/dotns.ts","../../src/identity/product-account.ts"],"names":["log","createLogger"],"mappings":"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","file":"index.js","sourcesContent":["// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\n/**\n * DotNS (Polkadot Name Service) utilities\n *\n * Provides name resolution for .dot domains\n */\n\nimport { createLogger } from \"@parity/product-sdk-logger\";\nimport type { DotNsRecord } from \"./types.js\";\n\nconst log = createLogger(\"identity\");\n\n/**\n * Check if a string is a valid DotNS name\n *\n * @param name - Name to validate\n * @returns True if valid DotNS name\n */\nexport function isValidDotNsName(name: string): boolean {\n // Basic validation: alphanumeric, hyphens, ends with .dot\n if (!name.endsWith(\".dot\")) return false;\n const label = name.slice(0, -4);\n if (label.length < 3 || label.length > 63) return false;\n return /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(label);\n}\n\n/**\n * Normalize a DotNS name (lowercase, trim whitespace)\n *\n * @param name - Name to normalize\n * @returns Normalized name\n */\nexport function normalizeDotNsName(name: string): string {\n let normalized = name.toLowerCase().trim();\n if (!normalized.endsWith(\".dot\")) {\n normalized += \".dot\";\n }\n return normalized;\n}\n\n/**\n * Resolve a DotNS name to an address\n *\n * @param name - DotNS name (e.g., \"alice.dot\")\n * @returns Resolved record or null if not found\n *\n * @example\n * ```ts\n * const record = await resolveDotNs('alice.dot');\n * if (record) {\n * console.log('Address:', record.address);\n * }\n * ```\n */\nexport async function resolveDotNs(name: string): Promise<DotNsRecord | null> {\n const normalized = normalizeDotNsName(name);\n\n if (!isValidDotNsName(normalized)) {\n log.warn(\"Invalid DotNS name\", { name });\n return null;\n }\n\n log.debug(\"Resolving DotNS name\", { name: normalized });\n\n // TODO: Implement via PAPI query to DotNS pallet\n throw new Error(\n \"resolveDotNs() is not yet implemented. \" +\n \"This is a skeleton for the Product SDK structure.\",\n );\n}\n\n/**\n * Reverse resolve an address to a DotNS name\n *\n * @param address - SS58 address\n * @returns Primary name or null if none set\n */\nexport async function reverseDotNs(address: string): Promise<string | null> {\n log.debug(\"Reverse resolving address\", { address });\n\n // TODO: Implement via PAPI query to DotNS pallet\n throw new Error(\n \"reverseDotNs() is not yet implemented. \" +\n \"This is a skeleton for the Product SDK structure.\",\n );\n}\n\n/**\n * Check if a DotNS name is available for registration\n *\n * @param name - Name to check\n * @returns True if available\n */\nexport async function isDotNsAvailable(name: string): Promise<boolean> {\n const record = await resolveDotNs(name).catch(() => null);\n return record === null;\n}\n","// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\n/**\n * Context alias derivation\n *\n * Derives a deterministic, context-bound alias from a parent account using blake2b-256.\n *\n * NOTE: this is NOT the canonical sr25519 product-account derivation used by\n * mobile, desktop, and dotli hosts. For that, use\n * `@parity/product-sdk-keys::deriveProductAccountPublicKey`.\n */\n\nimport { createLogger } from \"@parity/product-sdk-logger\";\nimport { blake2b256 } from \"@parity/product-sdk-crypto\";\nimport { ss58Encode, ss58Decode, deriveH160 } from \"@parity/product-sdk-address\";\nimport type { ContextAliasInfo, AnonymousAliasInfo, RingLocation } from \"./types.js\";\n\nconst log = createLogger(\"identity\");\n\n/**\n * Derive a context-bound alias from a parent account.\n *\n * The alias is deterministically derived using:\n * aliasPublicKey = blake2b256(parentPublicKey || context)\n *\n * @param parentAddress - Parent account SS58 address\n * @param context - Context string for derivation (e.g. an app id or scope label)\n * @param ss58Prefix - SS58 prefix (default: 42)\n * @returns Context alias info\n *\n * @example\n * ```ts\n * const alias = deriveContextAlias(\n * '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',\n * 'voting-round-1'\n * );\n * console.log('Alias address:', alias.address);\n * ```\n */\nexport function deriveContextAlias(\n parentAddress: string,\n context: string,\n ss58Prefix = 42,\n): ContextAliasInfo {\n const { publicKey: parentPublicKey } = ss58Decode(parentAddress);\n\n // Derive alias public key: blake2b-256(parentPublicKey || context)\n const contextBytes = new TextEncoder().encode(context);\n const combined = new Uint8Array(parentPublicKey.length + contextBytes.length);\n combined.set(parentPublicKey, 0);\n combined.set(contextBytes, parentPublicKey.length);\n\n const aliasPublicKey = blake2b256(combined);\n const address = ss58Encode(aliasPublicKey, ss58Prefix);\n const h160Address = deriveH160(aliasPublicKey);\n\n log.debug(\"Derived context alias\", {\n parentAddress,\n context,\n address,\n });\n\n return {\n address,\n h160Address,\n parentAddress,\n context,\n };\n}\n\n/**\n * Verify that a context alias was derived from a parent account.\n *\n * @param aliasAddress - Context alias SS58 address\n * @param parentAddress - Claimed parent address\n * @param context - Context string used for derivation\n * @returns True if derivation is valid\n */\nexport function verifyContextAlias(\n aliasAddress: string,\n parentAddress: string,\n context: string,\n): boolean {\n try {\n const derived = deriveContextAlias(parentAddress, context);\n const { publicKey: aliasKey } = ss58Decode(aliasAddress);\n const { publicKey: derivedKey } = ss58Decode(derived.address);\n\n // Compare public keys\n if (aliasKey.length !== derivedKey.length) return false;\n for (let i = 0; i < aliasKey.length; i++) {\n if (aliasKey[i] !== derivedKey[i]) return false;\n }\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Derive an anonymous alias using Ring VRF\n *\n * This creates a context-specific alias that cannot be linked\n * back to the original identity without the ring proof.\n *\n * @param context - Context for alias derivation (e.g., \"voting-round-1\")\n * @param ringLocation - Ring location for proof generation\n * @returns Anonymous alias info\n */\nexport function deriveAnonymousAlias(\n context: string,\n ringLocation: RingLocation,\n): AnonymousAliasInfo {\n log.debug(\"Deriving anonymous alias\", { context, ringLocation });\n\n // TODO: Implement Ring VRF alias derivation\n // This requires the Ring VRF implementation from TruAPI\n throw new Error(\n \"deriveAnonymousAlias() is not yet implemented. \" +\n \"This requires container mode with Ring VRF support.\",\n );\n}\n\n/**\n * Create a Ring VRF proof for a message\n *\n * @param message - Message to prove\n * @param ringLocation - Ring location\n * @returns Proof bytes\n */\nexport async function createRingProof(\n message: Uint8Array,\n ringLocation: RingLocation,\n): Promise<Uint8Array> {\n log.debug(\"Creating ring proof\", { ringLocation });\n\n // TODO: Implement Ring VRF proof creation via TruAPI\n throw new Error(\n \"createRingProof() is not yet implemented. \" +\n \"This requires container mode with Ring VRF support.\",\n );\n}\n\n/**\n * Verify a Ring VRF proof\n *\n * @param message - Original message\n * @param proof - Proof bytes\n * @param alias - Expected alias\n * @returns True if proof is valid\n */\nexport async function verifyRingProof(\n message: Uint8Array,\n proof: Uint8Array,\n alias: string,\n): Promise<boolean> {\n log.debug(\"Verifying ring proof\");\n\n // TODO: Implement Ring VRF proof verification\n throw new Error(\n \"verifyRingProof() is not yet implemented. \" +\n \"This requires container mode with Ring VRF support.\",\n );\n}\n"]}
|
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-
|
|
3
|
-
export { a as Account,
|
|
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 {
|
|
8
|
-
export {
|
|
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
|
|
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:
|
|
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
|
|
33
|
+
* // Custom cloud storage environment
|
|
34
34
|
* const prodApp = await createApp({
|
|
35
35
|
* name: 'my-app',
|
|
36
|
-
*
|
|
36
|
+
* cloudStorage: { environment: 'polkadot' },
|
|
37
37
|
* });
|
|
38
38
|
*
|
|
39
|
-
* // Disable
|
|
40
|
-
* const
|
|
39
|
+
* // Disable cloud storage entirely
|
|
40
|
+
* const noCloudStorageApp = await createApp({
|
|
41
41
|
* name: 'my-app',
|
|
42
|
-
*
|
|
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.
|
|
49
|
+
* await app.localStorage.set('key', 'value');
|
|
50
50
|
*
|
|
51
|
-
* // Use
|
|
52
|
-
* if (app.
|
|
53
|
-
* const cid = await app.
|
|
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
|
-
export { configure, createLogger } from './chunk-
|
|
2
|
-
export { createApp } from './chunk-
|
|
1
|
+
export { configure, createLogger } from './chunk-JVJ552RU.js';
|
|
2
|
+
export { createApp } from './chunk-JC4RBXLY.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 {
|
|
7
|
-
export {
|
|
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';
|
package/dist/react/index.d.ts
CHANGED
|
@@ -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-
|
|
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-
|
|
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.
|
|
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
|
-
*
|
|
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 }] =
|
|
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
|
|
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
|
|
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,
|
|
177
|
+
export { ProductSDKContext, ProductSDKProvider, type ProductSDKProviderProps, type UseWalletActions, type UseWalletReturn, type UseWalletState, useChain, useLocalStorage, useLocalStorageString, useProductSDK, useWallet };
|
package/dist/react/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createApp } from '../chunk-
|
|
1
|
+
import { createApp } from '../chunk-JC4RBXLY.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
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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,
|
|
188
|
+
export { ProductSDKContext, ProductSDKProvider, useChain, useLocalStorage, useLocalStorageString, useProductSDK, useWallet };
|
|
189
189
|
//# sourceMappingURL=index.js.map
|
|
190
190
|
//# sourceMappingURL=index.js.map
|
package/dist/react/index.js.map
CHANGED
|
@@ -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":"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","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":";;;;AAUO,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":["// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\n/**\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","// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\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","// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\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","// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\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","// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\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"]}
|