@parity/product-sdk 0.1.0 → 0.2.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.js +2 -2
- package/dist/address/index.js.map +1 -1
- package/dist/bulletin/index.js +2 -2
- package/dist/bulletin/index.js.map +1 -1
- package/dist/chain/index.js +2 -2
- package/dist/chain/index.js.map +1 -1
- package/dist/{chunk-NVGSGXGH.js → chunk-6W3TCR3W.js} +23 -19
- package/dist/chunk-6W3TCR3W.js.map +1 -0
- package/dist/chunk-XSKBA5SR.js +2 -7
- package/dist/chunk-XSKBA5SR.js.map +1 -1
- package/dist/contracts/index.js +2 -2
- package/dist/contracts/index.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +3 -12
- package/dist/core/index.js.map +1 -1
- package/dist/crypto/index.js +2 -2
- package/dist/crypto/index.js.map +1 -1
- package/dist/host/index.js +2 -2
- package/dist/host/index.js.map +1 -1
- package/dist/identity/index.js +8 -19
- package/dist/identity/index.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +8 -26
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +17 -40
- package/dist/react/index.js.map +1 -1
- package/dist/storage/index.js +2 -2
- package/dist/storage/index.js.map +1 -1
- package/dist/{types-CZQDzQ53.d.ts → types-CvHwLIWl.d.ts} +16 -7
- package/dist/wallet/index.js +2 -2
- package/dist/wallet/index.js.map +1 -1
- package/package.json +13 -13
- package/src/core/createApp.ts +28 -7
- package/src/core/types.ts +15 -6
- package/src/index.ts +1 -1
- package/dist/chunk-NVGSGXGH.js.map +0 -1
package/dist/address/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from '@parity/product-sdk-address';
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
package/dist/bulletin/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from '@parity/product-sdk-bulletin';
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
package/dist/chain/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from '@parity/product-sdk-chain-client';
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/chain/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
+
import { createLogger, configure } from '@parity/product-sdk-logger';
|
|
2
|
+
import { createKvStore } from '@parity/product-sdk-storage';
|
|
3
|
+
import { SignerManager } from '@parity/product-sdk-signer';
|
|
4
|
+
import { BulletinClient, createLazySigner, calculateCid } from '@parity/product-sdk-bulletin';
|
|
5
|
+
import { destroyAll, isConnected, createChainClient, getClient } from '@parity/product-sdk-chain-client';
|
|
6
|
+
|
|
1
7
|
// src/core/createApp.ts
|
|
2
|
-
import { configure, createLogger } from "@parity/product-sdk-logger";
|
|
3
|
-
import { createKvStore } from "@parity/product-sdk-storage";
|
|
4
|
-
import { SignerManager } from "@parity/product-sdk-signer";
|
|
5
|
-
import { BulletinClient, computeCid } from "@parity/product-sdk-bulletin";
|
|
6
|
-
import {
|
|
7
|
-
createChainClient,
|
|
8
|
-
getClient,
|
|
9
|
-
isConnected,
|
|
10
|
-
destroyAll
|
|
11
|
-
} from "@parity/product-sdk-chain-client";
|
|
12
8
|
var log = createLogger("app");
|
|
13
9
|
async function createApp(config) {
|
|
14
10
|
if (config.logLevel) {
|
|
@@ -21,7 +17,10 @@ async function createApp(config) {
|
|
|
21
17
|
});
|
|
22
18
|
const bulletinEnabled = config.bulletin !== false;
|
|
23
19
|
const bulletinEnvironment = typeof config.bulletin === "object" ? config.bulletin.environment : "paseo";
|
|
24
|
-
const bulletinClient = bulletinEnabled ? await BulletinClient.create(
|
|
20
|
+
const bulletinClient = bulletinEnabled ? await BulletinClient.create({
|
|
21
|
+
environment: bulletinEnvironment,
|
|
22
|
+
signer: createLazySigner(() => signerManager.getSigner())
|
|
23
|
+
}) : null;
|
|
25
24
|
if (bulletinEnabled) {
|
|
26
25
|
log.debug("Bulletin client initialized", { environment: bulletinEnvironment });
|
|
27
26
|
} else {
|
|
@@ -66,13 +65,19 @@ async function createApp(config) {
|
|
|
66
65
|
const bulletinApi = bulletinClient ? {
|
|
67
66
|
upload: async (data) => {
|
|
68
67
|
const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
69
|
-
const result = await bulletinClient.
|
|
70
|
-
|
|
68
|
+
const result = await bulletinClient.store(bytes).withManifest(true).send();
|
|
69
|
+
if (!result.cid) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
"Bulletin upload returned no CID despite .withManifest(true). Upstream contract may have shifted \u2014 file an issue."
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return result.cid.toString();
|
|
71
75
|
},
|
|
72
76
|
fetch: (cid) => bulletinClient.fetchBytes(cid),
|
|
73
|
-
computeCid: (data) => {
|
|
77
|
+
computeCid: async (data) => {
|
|
74
78
|
const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
75
|
-
|
|
79
|
+
const cid = await calculateCid(bytes);
|
|
80
|
+
return cid.toString();
|
|
76
81
|
}
|
|
77
82
|
} : null;
|
|
78
83
|
log.info("Product SDK app created", {
|
|
@@ -171,7 +176,6 @@ function createWalletApi(signerManager) {
|
|
|
171
176
|
};
|
|
172
177
|
}
|
|
173
178
|
|
|
174
|
-
export {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
//# sourceMappingURL=chunk-NVGSGXGH.js.map
|
|
179
|
+
export { createApp };
|
|
180
|
+
//# sourceMappingURL=chunk-6W3TCR3W.js.map
|
|
181
|
+
//# sourceMappingURL=chunk-6W3TCR3W.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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"]}
|
package/dist/chunk-XSKBA5SR.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export {
|
|
5
|
-
configure,
|
|
6
|
-
createLogger
|
|
7
|
-
};
|
|
1
|
+
export { configure, createLogger } from '@parity/product-sdk-logger';
|
|
2
|
+
//# sourceMappingURL=chunk-XSKBA5SR.js.map
|
|
8
3
|
//# sourceMappingURL=chunk-XSKBA5SR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-XSKBA5SR.js","sourcesContent":[]}
|
package/dist/contracts/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from '@parity/product-sdk-contracts';
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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-
|
|
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-CvHwLIWl.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';
|
package/dist/core/index.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "../chunk-XSKBA5SR.js";
|
|
5
|
-
import {
|
|
6
|
-
createApp
|
|
7
|
-
} from "../chunk-NVGSGXGH.js";
|
|
8
|
-
export {
|
|
9
|
-
configure,
|
|
10
|
-
createApp,
|
|
11
|
-
createLogger
|
|
12
|
-
};
|
|
1
|
+
export { configure, createLogger } from '../chunk-XSKBA5SR.js';
|
|
2
|
+
export { createApp } from '../chunk-6W3TCR3W.js';
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
13
4
|
//# sourceMappingURL=index.js.map
|
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
package/dist/crypto/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from '@parity/product-sdk-crypto';
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/crypto/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
package/dist/host/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from '@parity/product-sdk-host';
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/host/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
package/dist/identity/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { createLogger } from '@parity/product-sdk-logger';
|
|
2
|
+
import { blake2b256 } from '@parity/product-sdk-crypto';
|
|
3
|
+
import { ss58Decode, ss58Encode, deriveH160 } from '@parity/product-sdk-address';
|
|
4
|
+
|
|
1
5
|
// src/identity/dotns.ts
|
|
2
|
-
import { createLogger } from "@parity/product-sdk-logger";
|
|
3
6
|
var log = createLogger("identity");
|
|
4
7
|
function isValidDotNsName(name) {
|
|
5
8
|
if (!name.endsWith(".dot")) return false;
|
|
@@ -35,12 +38,7 @@ async function isDotNsAvailable(name) {
|
|
|
35
38
|
const record = await resolveDotNs(name).catch(() => null);
|
|
36
39
|
return record === null;
|
|
37
40
|
}
|
|
38
|
-
|
|
39
|
-
// src/identity/product-account.ts
|
|
40
|
-
import { createLogger as createLogger2 } from "@parity/product-sdk-logger";
|
|
41
|
-
import { blake2b256 } from "@parity/product-sdk-crypto";
|
|
42
|
-
import { ss58Encode, ss58Decode, deriveH160 } from "@parity/product-sdk-address";
|
|
43
|
-
var log2 = createLogger2("identity");
|
|
41
|
+
var log2 = createLogger("identity");
|
|
44
42
|
function deriveProductAccount(parentAddress, productName, ss58Prefix = 42) {
|
|
45
43
|
const { publicKey: parentPublicKey } = ss58Decode(parentAddress);
|
|
46
44
|
const productNameBytes = new TextEncoder().encode(productName);
|
|
@@ -94,16 +92,7 @@ async function verifyRingProof(message, proof, alias) {
|
|
|
94
92
|
"verifyRingProof() is not yet implemented. This requires container mode with Ring VRF support."
|
|
95
93
|
);
|
|
96
94
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
deriveProductAccount,
|
|
101
|
-
isDotNsAvailable,
|
|
102
|
-
isValidDotNsName,
|
|
103
|
-
normalizeDotNsName,
|
|
104
|
-
resolveDotNs,
|
|
105
|
-
reverseDotNs,
|
|
106
|
-
verifyProductAccount,
|
|
107
|
-
verifyRingProof
|
|
108
|
-
};
|
|
95
|
+
|
|
96
|
+
export { createRingProof, deriveAnonymousAlias, deriveProductAccount, isDotNsAvailable, isValidDotNsName, normalizeDotNsName, resolveDotNs, reverseDotNs, verifyProductAccount, verifyRingProof };
|
|
97
|
+
//# sourceMappingURL=index.js.map
|
|
109
98
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/identity/dotns.ts","../../src/identity/product-account.ts"],"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 * Product account derivation\n *\n * Derives product-scoped accounts from a parent account\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 { ProductAccountInfo, AnonymousAliasInfo, RingLocation } from \"./types.js\";\n\nconst log = createLogger(\"identity\");\n\n/**\n * Derive a product-scoped account from a parent account\n *\n * The product account is deterministically derived using:\n * productPublicKey = hash(parentPublicKey || productName)\n *\n * @param parentAddress - Parent account SS58 address\n * @param productName - Product name for derivation\n * @param ss58Prefix - SS58 prefix (default: 42)\n * @returns Product account info\n *\n * @example\n * ```ts\n * const productAccount = deriveProductAccount(\n * '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',\n * 'my-app'\n * );\n * console.log('Product address:', productAccount.address);\n * ```\n */\nexport function deriveProductAccount(\n parentAddress: string,\n productName: string,\n ss58Prefix = 42,\n): ProductAccountInfo {\n const { publicKey: parentPublicKey } = ss58Decode(parentAddress);\n\n // Derive product public key: blake2b-256(parentPublicKey || productName)\n const productNameBytes = new TextEncoder().encode(productName);\n const combined = new Uint8Array(parentPublicKey.length + productNameBytes.length);\n combined.set(parentPublicKey, 0);\n combined.set(productNameBytes, parentPublicKey.length);\n\n const productPublicKey = blake2b256(combined);\n const address = ss58Encode(productPublicKey, ss58Prefix);\n const h160Address = deriveH160(productPublicKey);\n\n log.debug(\"Derived product account\", {\n parentAddress,\n productName,\n address,\n });\n\n return {\n address,\n h160Address,\n parentAddress,\n productName,\n };\n}\n\n/**\n * Verify that a product account was derived from a parent account\n *\n * @param productAddress - Product account address\n * @param parentAddress - Claimed parent address\n * @param productName - Product name\n * @returns True if derivation is valid\n */\nexport function verifyProductAccount(\n productAddress: string,\n parentAddress: string,\n productName: string,\n): boolean {\n try {\n const derived = deriveProductAccount(parentAddress, productName);\n const { publicKey: productKey } = ss58Decode(productAddress);\n const { publicKey: derivedKey } = ss58Decode(derived.address);\n\n // Compare public keys\n if (productKey.length !== derivedKey.length) return false;\n for (let i = 0; i < productKey.length; i++) {\n if (productKey[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"],"mappings":"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","names":["createLogger","log"]}
|
|
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 * Product account derivation\n *\n * Derives product-scoped accounts from a parent account\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 { ProductAccountInfo, AnonymousAliasInfo, RingLocation } from \"./types.js\";\n\nconst log = createLogger(\"identity\");\n\n/**\n * Derive a product-scoped account from a parent account\n *\n * The product account is deterministically derived using:\n * productPublicKey = hash(parentPublicKey || productName)\n *\n * @param parentAddress - Parent account SS58 address\n * @param productName - Product name for derivation\n * @param ss58Prefix - SS58 prefix (default: 42)\n * @returns Product account info\n *\n * @example\n * ```ts\n * const productAccount = deriveProductAccount(\n * '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',\n * 'my-app'\n * );\n * console.log('Product address:', productAccount.address);\n * ```\n */\nexport function deriveProductAccount(\n parentAddress: string,\n productName: string,\n ss58Prefix = 42,\n): ProductAccountInfo {\n const { publicKey: parentPublicKey } = ss58Decode(parentAddress);\n\n // Derive product public key: blake2b-256(parentPublicKey || productName)\n const productNameBytes = new TextEncoder().encode(productName);\n const combined = new Uint8Array(parentPublicKey.length + productNameBytes.length);\n combined.set(parentPublicKey, 0);\n combined.set(productNameBytes, parentPublicKey.length);\n\n const productPublicKey = blake2b256(combined);\n const address = ss58Encode(productPublicKey, ss58Prefix);\n const h160Address = deriveH160(productPublicKey);\n\n log.debug(\"Derived product account\", {\n parentAddress,\n productName,\n address,\n });\n\n return {\n address,\n h160Address,\n parentAddress,\n productName,\n };\n}\n\n/**\n * Verify that a product account was derived from a parent account\n *\n * @param productAddress - Product account address\n * @param parentAddress - Claimed parent address\n * @param productName - Product name\n * @returns True if derivation is valid\n */\nexport function verifyProductAccount(\n productAddress: string,\n parentAddress: string,\n productName: string,\n): boolean {\n try {\n const derived = deriveProductAccount(parentAddress, productName);\n const { publicKey: productKey } = ss58Decode(productAddress);\n const { publicKey: derivedKey } = ss58Decode(derived.address);\n\n // Compare public keys\n if (productKey.length !== derivedKey.length) return false;\n for (let i = 0; i < productKey.length; i++) {\n if (productKey[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,11 +1,11 @@
|
|
|
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, B as BulletinApi, C as ChainApi, S as StorageApi, W as WalletApi } from './types-
|
|
2
|
+
import { b as AppConfig, A as App } from './types-CvHwLIWl.js';
|
|
3
|
+
export { a as Account, B as BulletinApi, C as ChainApi, S as StorageApi, W as WalletApi } from './types-CvHwLIWl.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
7
|
export { createKvStore } from '@parity/product-sdk-storage';
|
|
8
|
-
export { BulletinClient,
|
|
8
|
+
export { BulletinClient, calculateCid } from '@parity/product-sdk-bulletin';
|
|
9
9
|
export { ChainDefinition, PolkadotClient, TypedApi } from 'polkadot-api';
|
|
10
10
|
|
|
11
11
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,27 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from
|
|
8
|
-
|
|
9
|
-
// src/index.ts
|
|
10
|
-
import { isInsideContainer, isInsideContainerSync } from "@parity/product-sdk-host";
|
|
11
|
-
import { createChainClient } from "@parity/product-sdk-chain-client";
|
|
12
|
-
import { SignerManager } from "@parity/product-sdk-signer";
|
|
13
|
-
import { createKvStore } from "@parity/product-sdk-storage";
|
|
14
|
-
import { BulletinClient, computeCid } from "@parity/product-sdk-bulletin";
|
|
15
|
-
export {
|
|
16
|
-
BulletinClient,
|
|
17
|
-
SignerManager,
|
|
18
|
-
computeCid,
|
|
19
|
-
configure,
|
|
20
|
-
createApp,
|
|
21
|
-
createChainClient,
|
|
22
|
-
createKvStore,
|
|
23
|
-
createLogger,
|
|
24
|
-
isInsideContainer,
|
|
25
|
-
isInsideContainerSync
|
|
26
|
-
};
|
|
1
|
+
export { configure, createLogger } from './chunk-XSKBA5SR.js';
|
|
2
|
+
export { createApp } from './chunk-6W3TCR3W.js';
|
|
3
|
+
export { isInsideContainer, isInsideContainerSync } from '@parity/product-sdk-host';
|
|
4
|
+
export { createChainClient } from '@parity/product-sdk-chain-client';
|
|
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';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
27
9
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ 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-CvHwLIWl.js';
|
|
6
6
|
import { ChainDefinition, TypedApi } from 'polkadot-api';
|
|
7
7
|
import '@parity/product-sdk-bulletin';
|
|
8
8
|
import '@parity/product-sdk-chain-client';
|
package/dist/react/index.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
} from
|
|
1
|
+
import { createApp } from '../chunk-6W3TCR3W.js';
|
|
2
|
+
import { createContext, useContext, useState, useEffect, useCallback, useMemo } from 'react';
|
|
3
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
|
-
// src/react/provider.tsx
|
|
6
|
-
import { useEffect, useState } from "react";
|
|
7
|
-
|
|
8
|
-
// src/react/context.ts
|
|
9
|
-
import { createContext, useContext } from "react";
|
|
10
5
|
var ProductSDKContext = createContext(null);
|
|
11
6
|
function useProductSDK() {
|
|
12
7
|
const app = useContext(ProductSDKContext);
|
|
@@ -17,9 +12,6 @@ function useProductSDK() {
|
|
|
17
12
|
}
|
|
18
13
|
return app;
|
|
19
14
|
}
|
|
20
|
-
|
|
21
|
-
// src/react/provider.tsx
|
|
22
|
-
import { Fragment, jsx } from "react/jsx-runtime";
|
|
23
15
|
function ProductSDKProvider({
|
|
24
16
|
name,
|
|
25
17
|
logLevel = "info",
|
|
@@ -51,12 +43,9 @@ function ProductSDKProvider({
|
|
|
51
43
|
}
|
|
52
44
|
return /* @__PURE__ */ jsx(ProductSDKContext.Provider, { value: app, children });
|
|
53
45
|
}
|
|
54
|
-
|
|
55
|
-
// src/react/useWallet.ts
|
|
56
|
-
import { useState as useState2, useEffect as useEffect2, useCallback } from "react";
|
|
57
46
|
function useWallet() {
|
|
58
47
|
const app = useProductSDK();
|
|
59
|
-
const [state, setState] =
|
|
48
|
+
const [state, setState] = useState({
|
|
60
49
|
isConnected: false,
|
|
61
50
|
isConnecting: false,
|
|
62
51
|
accounts: [],
|
|
@@ -106,7 +95,7 @@ function useWallet() {
|
|
|
106
95
|
},
|
|
107
96
|
[app]
|
|
108
97
|
);
|
|
109
|
-
|
|
98
|
+
useEffect(() => {
|
|
110
99
|
const unsubscribe = app.wallet.onAccountChange((account) => {
|
|
111
100
|
setState((s) => ({ ...s, selectedAccount: account }));
|
|
112
101
|
});
|
|
@@ -120,15 +109,12 @@ function useWallet() {
|
|
|
120
109
|
signMessage
|
|
121
110
|
};
|
|
122
111
|
}
|
|
123
|
-
|
|
124
|
-
// src/react/useStorage.ts
|
|
125
|
-
import { useState as useState3, useEffect as useEffect3, useCallback as useCallback2 } from "react";
|
|
126
112
|
function useStorage(key, defaultValue) {
|
|
127
113
|
const app = useProductSDK();
|
|
128
|
-
const [value, setValue] =
|
|
129
|
-
const [loading, setLoading] =
|
|
130
|
-
const [error, setError] =
|
|
131
|
-
|
|
114
|
+
const [value, setValue] = useState(null);
|
|
115
|
+
const [loading, setLoading] = useState(true);
|
|
116
|
+
const [error, setError] = useState(null);
|
|
117
|
+
useEffect(() => {
|
|
132
118
|
let mounted = true;
|
|
133
119
|
const loadValue = async () => {
|
|
134
120
|
try {
|
|
@@ -150,7 +136,7 @@ function useStorage(key, defaultValue) {
|
|
|
150
136
|
mounted = false;
|
|
151
137
|
};
|
|
152
138
|
}, [app, key, defaultValue]);
|
|
153
|
-
const setStoredValue =
|
|
139
|
+
const setStoredValue = useCallback(
|
|
154
140
|
async (newValue) => {
|
|
155
141
|
try {
|
|
156
142
|
setError(null);
|
|
@@ -167,9 +153,9 @@ function useStorage(key, defaultValue) {
|
|
|
167
153
|
}
|
|
168
154
|
function useStorageString(key, defaultValue) {
|
|
169
155
|
const app = useProductSDK();
|
|
170
|
-
const [value, setValue] =
|
|
171
|
-
const [loading, setLoading] =
|
|
172
|
-
|
|
156
|
+
const [value, setValue] = useState(null);
|
|
157
|
+
const [loading, setLoading] = useState(true);
|
|
158
|
+
useEffect(() => {
|
|
173
159
|
let mounted = true;
|
|
174
160
|
const loadValue = async () => {
|
|
175
161
|
const stored = await app.storage.get(key);
|
|
@@ -183,7 +169,7 @@ function useStorageString(key, defaultValue) {
|
|
|
183
169
|
mounted = false;
|
|
184
170
|
};
|
|
185
171
|
}, [app, key, defaultValue]);
|
|
186
|
-
const setStoredValue =
|
|
172
|
+
const setStoredValue = useCallback(
|
|
187
173
|
async (newValue) => {
|
|
188
174
|
await app.storage.set(key, newValue);
|
|
189
175
|
setValue(newValue);
|
|
@@ -192,22 +178,13 @@ function useStorageString(key, defaultValue) {
|
|
|
192
178
|
);
|
|
193
179
|
return [value, setStoredValue, { loading }];
|
|
194
180
|
}
|
|
195
|
-
|
|
196
|
-
// src/react/useChain.ts
|
|
197
|
-
import { useMemo } from "react";
|
|
198
181
|
function useChain(chain) {
|
|
199
182
|
const app = useProductSDK();
|
|
200
183
|
return useMemo(() => {
|
|
201
184
|
return app.chain.getClient(chain);
|
|
202
185
|
}, [app, chain]);
|
|
203
186
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
useChain,
|
|
208
|
-
useProductSDK,
|
|
209
|
-
useStorage,
|
|
210
|
-
useStorageString,
|
|
211
|
-
useWallet
|
|
212
|
-
};
|
|
187
|
+
|
|
188
|
+
export { ProductSDKContext, ProductSDKProvider, useChain, useProductSDK, useStorage, useStorageString, useWallet };
|
|
189
|
+
//# sourceMappingURL=index.js.map
|
|
213
190
|
//# sourceMappingURL=index.js.map
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/provider.tsx","../../src/react/context.ts","../../src/react/useWallet.ts","../../src/react/useStorage.ts","../../src/react/useChain.ts"],"sourcesContent":["/**\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 * 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 * 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"],"mappings":"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","names":["useState","useEffect","useState","useEffect","useState","useEffect","useCallback","useState","useEffect","useCallback"]}
|
|
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"]}
|
package/dist/storage/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from '@parity/product-sdk-storage';
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LogLevel } from '@parity/product-sdk-logger';
|
|
2
|
-
import {
|
|
2
|
+
import { BulletinEnvironment } from '@parity/product-sdk-bulletin';
|
|
3
3
|
import { ChainClient } from '@parity/product-sdk-chain-client';
|
|
4
4
|
import { ChainDefinition, TypedApi, PolkadotClient } from 'polkadot-api';
|
|
5
5
|
|
|
@@ -10,7 +10,7 @@ import { ChainDefinition, TypedApi, PolkadotClient } from 'polkadot-api';
|
|
|
10
10
|
/** Bulletin configuration options */
|
|
11
11
|
interface BulletinConfig {
|
|
12
12
|
/** Bulletin environment to connect to */
|
|
13
|
-
environment:
|
|
13
|
+
environment: BulletinEnvironment;
|
|
14
14
|
}
|
|
15
15
|
/** Configuration for createApp */
|
|
16
16
|
interface AppConfig {
|
|
@@ -109,12 +109,21 @@ interface ChainApi {
|
|
|
109
109
|
}
|
|
110
110
|
/** Bulletin Chain API exposed by the SDK */
|
|
111
111
|
interface BulletinApi {
|
|
112
|
-
/**
|
|
112
|
+
/**
|
|
113
|
+
* Upload data to Bulletin Chain.
|
|
114
|
+
*
|
|
115
|
+
* Requires a wallet to be connected and an account selected. Throws
|
|
116
|
+
* "No signer available …" otherwise.
|
|
117
|
+
*/
|
|
113
118
|
upload(data: string | Uint8Array): Promise<string>;
|
|
114
|
-
/** Fetch data by CID */
|
|
119
|
+
/** Fetch data by CID. */
|
|
115
120
|
fetch(cid: string): Promise<Uint8Array>;
|
|
116
|
-
/**
|
|
117
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Compute the CID for data without uploading.
|
|
123
|
+
*
|
|
124
|
+
* Async because the underlying hash is computed via Web Crypto.
|
|
125
|
+
*/
|
|
126
|
+
computeCid(data: string | Uint8Array): Promise<string>;
|
|
118
127
|
}
|
|
119
128
|
/** The main App instance returned by createApp */
|
|
120
129
|
interface App {
|
|
@@ -135,7 +144,7 @@ interface Account {
|
|
|
135
144
|
address: string;
|
|
136
145
|
/** Account name/label (if available) */
|
|
137
146
|
name?: string;
|
|
138
|
-
/** Source of the account (
|
|
147
|
+
/** Source of the account (host, dev signer, etc.) */
|
|
139
148
|
source: string;
|
|
140
149
|
}
|
|
141
150
|
|
package/dist/wallet/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from '@parity/product-sdk-signer';
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/wallet/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parity/product-sdk",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Unified SDK for building products in the Polkadot ecosystem - umbrella package",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -62,18 +62,18 @@
|
|
|
62
62
|
"src"
|
|
63
63
|
],
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"polkadot-api": "^1.
|
|
66
|
-
"@parity/product-sdk-address": "0.1.
|
|
67
|
-
"@parity/product-sdk-bulletin": "0.1
|
|
68
|
-
"@parity/product-sdk-chain-client": "0.1
|
|
69
|
-
"@parity/product-sdk-contracts": "0.1
|
|
70
|
-
"@parity/product-sdk-crypto": "0.1.
|
|
71
|
-
"@parity/product-sdk-host": "0.
|
|
72
|
-
"@parity/product-sdk-keys": "0.
|
|
73
|
-
"@parity/product-sdk-logger": "0.1.
|
|
74
|
-
"@parity/product-sdk-
|
|
75
|
-
"@parity/product-sdk-
|
|
76
|
-
"@parity/product-sdk-
|
|
65
|
+
"polkadot-api": "^2.1.2",
|
|
66
|
+
"@parity/product-sdk-address": "0.1.1",
|
|
67
|
+
"@parity/product-sdk-bulletin": "0.2.1",
|
|
68
|
+
"@parity/product-sdk-chain-client": "0.2.1",
|
|
69
|
+
"@parity/product-sdk-contracts": "0.2.1",
|
|
70
|
+
"@parity/product-sdk-crypto": "0.1.1",
|
|
71
|
+
"@parity/product-sdk-host": "0.2.0",
|
|
72
|
+
"@parity/product-sdk-keys": "0.2.0",
|
|
73
|
+
"@parity/product-sdk-logger": "0.1.1",
|
|
74
|
+
"@parity/product-sdk-signer": "0.2.1",
|
|
75
|
+
"@parity/product-sdk-storage": "0.1.1",
|
|
76
|
+
"@parity/product-sdk-tx": "0.2.0"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|
|
79
79
|
"react": "^18.0.0 || ^19.0.0"
|
package/src/core/createApp.ts
CHANGED
|
@@ -17,7 +17,7 @@ import type {
|
|
|
17
17
|
import { configure, createLogger } from "@parity/product-sdk-logger";
|
|
18
18
|
import { createKvStore } from "@parity/product-sdk-storage";
|
|
19
19
|
import { SignerManager } from "@parity/product-sdk-signer";
|
|
20
|
-
import { BulletinClient,
|
|
20
|
+
import { BulletinClient, calculateCid, createLazySigner } from "@parity/product-sdk-bulletin";
|
|
21
21
|
import {
|
|
22
22
|
createChainClient,
|
|
23
23
|
getClient,
|
|
@@ -83,12 +83,20 @@ export async function createApp(config: AppConfig): Promise<App> {
|
|
|
83
83
|
dappName: config.name,
|
|
84
84
|
});
|
|
85
85
|
|
|
86
|
-
// Initialize bulletin client (configurable, defaults to paseo)
|
|
86
|
+
// Initialize bulletin client (configurable, defaults to paseo).
|
|
87
|
+
//
|
|
88
|
+
// The signer is wrapped lazily so the bulletin client can be built before
|
|
89
|
+
// an account is selected. Uploads will throw a clear error if no signer
|
|
90
|
+
// is available at submission time. Reads (fetch / fetchJson) don't need
|
|
91
|
+
// a signer and work regardless.
|
|
87
92
|
const bulletinEnabled = config.bulletin !== false;
|
|
88
93
|
const bulletinEnvironment =
|
|
89
94
|
typeof config.bulletin === "object" ? config.bulletin.environment : "paseo";
|
|
90
95
|
const bulletinClient = bulletinEnabled
|
|
91
|
-
? await BulletinClient.create(
|
|
96
|
+
? await BulletinClient.create({
|
|
97
|
+
environment: bulletinEnvironment,
|
|
98
|
+
signer: createLazySigner(() => signerManager.getSigner()),
|
|
99
|
+
})
|
|
92
100
|
: null;
|
|
93
101
|
|
|
94
102
|
if (bulletinEnabled) {
|
|
@@ -150,13 +158,26 @@ export async function createApp(config: AppConfig): Promise<App> {
|
|
|
150
158
|
? {
|
|
151
159
|
upload: async (data) => {
|
|
152
160
|
const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
153
|
-
|
|
154
|
-
|
|
161
|
+
// Explicitly request a DAG-PB manifest so chunked uploads always
|
|
162
|
+
// resolve to a single root CID. Without this, AsyncBulletinClient
|
|
163
|
+
// can return `result.cid: undefined` for chunked-without-manifest
|
|
164
|
+
// uploads — but BulletinApi.upload promises a string return, and
|
|
165
|
+
// app consumers expect a CID they can hand to `fetch(cid)`. Keep
|
|
166
|
+
// the defensive null-check below as belt-and-braces in case the
|
|
167
|
+
// upstream contract shifts.
|
|
168
|
+
const result = await bulletinClient.store(bytes).withManifest(true).send();
|
|
169
|
+
if (!result.cid) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
"Bulletin upload returned no CID despite .withManifest(true). Upstream contract may have shifted — file an issue.",
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
return result.cid.toString();
|
|
155
175
|
},
|
|
156
176
|
fetch: (cid) => bulletinClient.fetchBytes(cid),
|
|
157
|
-
computeCid: (data) => {
|
|
177
|
+
computeCid: async (data) => {
|
|
158
178
|
const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
159
|
-
|
|
179
|
+
const cid = await calculateCid(bytes);
|
|
180
|
+
return cid.toString();
|
|
160
181
|
},
|
|
161
182
|
}
|
|
162
183
|
: null;
|
package/src/core/types.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { LogLevel } from "@parity/product-sdk-logger";
|
|
6
|
-
import type {
|
|
6
|
+
import type { BulletinEnvironment } from "@parity/product-sdk-bulletin";
|
|
7
7
|
import type { ChainClient } from "@parity/product-sdk-chain-client";
|
|
8
8
|
import type { ChainDefinition, TypedApi, PolkadotClient } from "polkadot-api";
|
|
9
9
|
|
|
@@ -119,12 +119,21 @@ export interface ChainApi {
|
|
|
119
119
|
|
|
120
120
|
/** Bulletin Chain API exposed by the SDK */
|
|
121
121
|
export interface BulletinApi {
|
|
122
|
-
/**
|
|
122
|
+
/**
|
|
123
|
+
* Upload data to Bulletin Chain.
|
|
124
|
+
*
|
|
125
|
+
* Requires a wallet to be connected and an account selected. Throws
|
|
126
|
+
* "No signer available …" otherwise.
|
|
127
|
+
*/
|
|
123
128
|
upload(data: string | Uint8Array): Promise<string>;
|
|
124
|
-
/** Fetch data by CID */
|
|
129
|
+
/** Fetch data by CID. */
|
|
125
130
|
fetch(cid: string): Promise<Uint8Array>;
|
|
126
|
-
/**
|
|
127
|
-
|
|
131
|
+
/**
|
|
132
|
+
* Compute the CID for data without uploading.
|
|
133
|
+
*
|
|
134
|
+
* Async because the underlying hash is computed via Web Crypto.
|
|
135
|
+
*/
|
|
136
|
+
computeCid(data: string | Uint8Array): Promise<string>;
|
|
128
137
|
}
|
|
129
138
|
|
|
130
139
|
/** The main App instance returned by createApp */
|
|
@@ -147,7 +156,7 @@ export interface Account {
|
|
|
147
156
|
address: string;
|
|
148
157
|
/** Account name/label (if available) */
|
|
149
158
|
name?: string;
|
|
150
|
-
/** Source of the account (
|
|
159
|
+
/** Source of the account (host, dev signer, etc.) */
|
|
151
160
|
source: string;
|
|
152
161
|
}
|
|
153
162
|
|
package/src/index.ts
CHANGED
|
@@ -46,4 +46,4 @@ export { isInsideContainer, isInsideContainerSync } from "@parity/product-sdk-ho
|
|
|
46
46
|
export { createChainClient } from "@parity/product-sdk-chain-client";
|
|
47
47
|
export { SignerManager } from "@parity/product-sdk-signer";
|
|
48
48
|
export { createKvStore } from "@parity/product-sdk-storage";
|
|
49
|
-
export { BulletinClient,
|
|
49
|
+
export { BulletinClient, calculateCid } from "@parity/product-sdk-bulletin";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/createApp.ts"],"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, computeCid } 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 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(bulletinEnvironment)\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 const result = await bulletinClient.upload(bytes);\n return result.cid;\n },\n fetch: (cid) => bulletinClient.fetchBytes(cid),\n computeCid: (data) => {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n return computeCid(bytes);\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"],"mappings":"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","names":[]}
|