@opendatalabs/vana-sdk 0.1.0-alpha.a25bcc7 → 0.1.0-alpha.a6b60fc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/dist/browser.cjs.map +1 -1
  2. package/dist/browser.d.ts +33 -1
  3. package/dist/browser.js.map +1 -1
  4. package/dist/chains/index.cjs.map +1 -1
  5. package/dist/chains/index.d.ts +30 -1
  6. package/dist/chains/index.js.map +1 -1
  7. package/dist/config/chains.cjs.map +1 -1
  8. package/dist/config/chains.d.ts +99 -0
  9. package/dist/config/chains.js.map +1 -1
  10. package/dist/contracts/contractController.cjs.map +1 -1
  11. package/dist/contracts/contractController.d.ts +66 -10
  12. package/dist/contracts/contractController.js.map +1 -1
  13. package/dist/controllers/data.cjs +172 -140
  14. package/dist/controllers/data.cjs.map +1 -1
  15. package/dist/controllers/data.d.ts +213 -175
  16. package/dist/controllers/data.js +172 -140
  17. package/dist/controllers/data.js.map +1 -1
  18. package/dist/controllers/permissions.cjs +184 -190
  19. package/dist/controllers/permissions.cjs.map +1 -1
  20. package/dist/controllers/permissions.d.ts +29 -73
  21. package/dist/controllers/permissions.js +184 -190
  22. package/dist/controllers/permissions.js.map +1 -1
  23. package/dist/controllers/protocol.cjs.map +1 -1
  24. package/dist/controllers/protocol.d.ts +27 -28
  25. package/dist/controllers/protocol.js.map +1 -1
  26. package/dist/controllers/schemas.cjs +19 -17
  27. package/dist/controllers/schemas.cjs.map +1 -1
  28. package/dist/controllers/schemas.d.ts +47 -40
  29. package/dist/controllers/schemas.js +19 -17
  30. package/dist/controllers/schemas.js.map +1 -1
  31. package/dist/controllers/server.cjs +17 -15
  32. package/dist/controllers/server.cjs.map +1 -1
  33. package/dist/controllers/server.d.ts +46 -38
  34. package/dist/controllers/server.js +17 -15
  35. package/dist/controllers/server.js.map +1 -1
  36. package/dist/core/apiClient.cjs +53 -3
  37. package/dist/core/apiClient.cjs.map +1 -1
  38. package/dist/core/apiClient.d.ts +132 -7
  39. package/dist/core/apiClient.js +53 -3
  40. package/dist/core/apiClient.js.map +1 -1
  41. package/dist/core/generics.cjs +30 -3
  42. package/dist/core/generics.cjs.map +1 -1
  43. package/dist/core/generics.d.ts +95 -6
  44. package/dist/core/generics.js +30 -3
  45. package/dist/core/generics.js.map +1 -1
  46. package/dist/core.cjs +29 -12
  47. package/dist/core.cjs.map +1 -1
  48. package/dist/core.d.ts +2 -1
  49. package/dist/core.js +29 -12
  50. package/dist/core.js.map +1 -1
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.js.map +1 -1
  53. package/dist/index.node.cjs +3 -3
  54. package/dist/index.node.cjs.map +1 -1
  55. package/dist/index.node.d.ts +8 -9
  56. package/dist/index.node.js +2 -2
  57. package/dist/index.node.js.map +1 -1
  58. package/dist/node.cjs.map +1 -1
  59. package/dist/node.d.ts +39 -1
  60. package/dist/node.js.map +1 -1
  61. package/dist/platform/browser.cjs +160 -2
  62. package/dist/platform/browser.cjs.map +1 -1
  63. package/dist/platform/browser.d.ts +232 -12
  64. package/dist/platform/browser.js +160 -2
  65. package/dist/platform/browser.js.map +1 -1
  66. package/dist/platform/interface.cjs.map +1 -1
  67. package/dist/platform/interface.d.ts +283 -90
  68. package/dist/platform/node.cjs +163 -2
  69. package/dist/platform/node.cjs.map +1 -1
  70. package/dist/platform/node.d.ts +69 -6
  71. package/dist/platform/node.js +163 -2
  72. package/dist/platform/node.js.map +1 -1
  73. package/dist/server/relayerHandler.cjs +214 -0
  74. package/dist/server/relayerHandler.cjs.map +1 -0
  75. package/dist/server/relayerHandler.d.ts +36 -0
  76. package/dist/server/relayerHandler.js +190 -0
  77. package/dist/server/relayerHandler.js.map +1 -0
  78. package/dist/storage/manager.cjs +108 -25
  79. package/dist/storage/manager.cjs.map +1 -1
  80. package/dist/storage/manager.d.ts +119 -25
  81. package/dist/storage/manager.js +108 -25
  82. package/dist/storage/manager.js.map +1 -1
  83. package/dist/storage/providers/callback-storage.cjs +86 -15
  84. package/dist/storage/providers/callback-storage.cjs.map +1 -1
  85. package/dist/storage/providers/callback-storage.d.ts +109 -20
  86. package/dist/storage/providers/callback-storage.js +86 -15
  87. package/dist/storage/providers/callback-storage.js.map +1 -1
  88. package/dist/storage/providers/pinata.cjs.map +1 -1
  89. package/dist/storage/providers/pinata.d.ts +12 -14
  90. package/dist/storage/providers/pinata.js.map +1 -1
  91. package/dist/tests/factories/mockFactory.d.ts +2 -2
  92. package/dist/tests/relayer-integration.test.d.ts +1 -0
  93. package/dist/tests/relayer-unified.test.d.ts +1 -0
  94. package/dist/tests/server-relayer-handler.test.d.ts +1 -0
  95. package/dist/types/blockchain.cjs.map +1 -1
  96. package/dist/types/blockchain.d.ts +39 -11
  97. package/dist/types/chains.cjs.map +1 -1
  98. package/dist/types/chains.d.ts +74 -7
  99. package/dist/types/chains.js.map +1 -1
  100. package/dist/types/config.cjs.map +1 -1
  101. package/dist/types/config.d.ts +46 -191
  102. package/dist/types/config.js.map +1 -1
  103. package/dist/types/contracts.cjs.map +1 -1
  104. package/dist/types/contracts.d.ts +71 -7
  105. package/dist/types/controller-context.cjs.map +1 -1
  106. package/dist/types/controller-context.d.ts +3 -2
  107. package/dist/types/data.cjs.map +1 -1
  108. package/dist/types/data.d.ts +4 -6
  109. package/dist/types/generics.cjs.map +1 -1
  110. package/dist/types/generics.d.ts +80 -9
  111. package/dist/types/index.cjs.map +1 -1
  112. package/dist/types/index.d.ts +27 -2
  113. package/dist/types/index.js.map +1 -1
  114. package/dist/types/operations.cjs.map +1 -1
  115. package/dist/types/operations.d.ts +132 -15
  116. package/dist/types/operations.js.map +1 -1
  117. package/dist/types/permissions.cjs.map +1 -1
  118. package/dist/types/permissions.d.ts +15 -20
  119. package/dist/types/personal.cjs.map +1 -1
  120. package/dist/types/personal.d.ts +131 -14
  121. package/dist/types/relayer.cjs.map +1 -1
  122. package/dist/types/relayer.d.ts +262 -35
  123. package/dist/types/storage.cjs.map +1 -1
  124. package/dist/types/storage.d.ts +9 -21
  125. package/dist/types/storage.js.map +1 -1
  126. package/dist/utils/grantFiles.cjs.map +1 -1
  127. package/dist/utils/grantFiles.d.ts +10 -20
  128. package/dist/utils/grantFiles.js.map +1 -1
  129. package/dist/utils/grantValidation.cjs.map +1 -1
  130. package/dist/utils/grantValidation.d.ts +95 -16
  131. package/dist/utils/grantValidation.js.map +1 -1
  132. package/dist/utils/grants.cjs.map +1 -1
  133. package/dist/utils/grants.d.ts +93 -12
  134. package/dist/utils/grants.js.map +1 -1
  135. package/dist/utils/lazy-import.cjs.map +1 -1
  136. package/dist/utils/lazy-import.d.ts +32 -7
  137. package/dist/utils/lazy-import.js.map +1 -1
  138. package/dist/utils/signatureCache.cjs +8 -2
  139. package/dist/utils/signatureCache.cjs.map +1 -1
  140. package/dist/utils/signatureCache.d.ts +49 -8
  141. package/dist/utils/signatureCache.js +8 -2
  142. package/dist/utils/signatureCache.js.map +1 -1
  143. package/dist/utils/transactionHelpers.cjs.map +1 -1
  144. package/dist/utils/transactionHelpers.d.ts +12 -12
  145. package/dist/utils/transactionHelpers.js.map +1 -1
  146. package/dist/utils/typedDataConverter.cjs.map +1 -1
  147. package/dist/utils/typedDataConverter.d.ts +39 -3
  148. package/dist/utils/typedDataConverter.js.map +1 -1
  149. package/dist/utils/urlResolver.cjs +7 -0
  150. package/dist/utils/urlResolver.cjs.map +1 -1
  151. package/dist/utils/urlResolver.d.ts +22 -4
  152. package/dist/utils/urlResolver.js +7 -0
  153. package/dist/utils/urlResolver.js.map +1 -1
  154. package/dist/utils/wallet.cjs +2 -1
  155. package/dist/utils/wallet.cjs.map +1 -1
  156. package/dist/utils/wallet.d.ts +78 -16
  157. package/dist/utils/wallet.js +2 -1
  158. package/dist/utils/wallet.js.map +1 -1
  159. package/package.json +1 -1
  160. package/dist/server/handler.cjs +0 -101
  161. package/dist/server/handler.cjs.map +0 -1
  162. package/dist/server/handler.d.ts +0 -87
  163. package/dist/server/handler.js +0 -77
  164. package/dist/server/handler.js.map +0 -1
  165. /package/dist/tests/{server-handler.test.d.ts → permissions-revoke-relayer.test.d.ts} +0 -0
@@ -22,40 +22,42 @@ class SchemaController extends BaseController {
22
22
  super(context);
23
23
  }
24
24
  /**
25
- * Creates a new schema with automatic validation and IPFS upload.
25
+ * Creates a schema with validation and IPFS upload.
26
26
  *
27
27
  * @remarks
28
- * This is the primary method for creating schemas on the Vana network. It handles
29
- * the complete workflow including schema validation, IPFS upload, and blockchain
30
- * registration. The schema definition is stored unencrypted on IPFS to enable
31
- * public access and reusability.
28
+ * Primary method for schema creation. Validates definition,
29
+ * uploads to IPFS (unencrypted for reusability), and registers
30
+ * on blockchain. Schema becomes immediately available network-wide.
32
31
  *
33
- * The method automatically:
34
- * - Validates the schema definition against the Vana metaschema
35
- * - Uploads the definition to IPFS to generate a permanent URL
36
- * - Registers the schema on the blockchain with the generated URL
32
+ * @param params - Creation configuration
33
+ * @param params.name - Human-readable schema name
34
+ * @param params.dialect - Schema format (`"json"` or `"sqlite"`)
35
+ * @param params.schema - Definition object or JSON string
36
+ *
37
+ * @returns Schema ID, IPFS URL, and transaction hash
38
+ *
39
+ * @throws {SchemaValidationError} Invalid schema definition.
40
+ * Verify schema follows JSON Schema or SQLite format.
41
+ * @throws {Error} Storage not configured.
42
+ * Configure storage providers in VanaConfig.
43
+ * @throws {Error} IPFS upload failed.
44
+ * Check network and storage provider status.
37
45
  *
38
- * @param params - Schema creation parameters including name, dialect, and definition
39
- * @returns Promise resolving to creation results with schema ID and transaction hash
40
- * @throws {SchemaValidationError} When the schema definition is invalid
41
- * @throws {Error} When IPFS upload or blockchain registration fails
42
46
  * @example
43
47
  * ```typescript
44
- * // Create a JSON schema for user profiles
45
48
  * const result = await vana.schemas.create({
46
49
  * name: "User Profile",
47
50
  * dialect: "json",
48
51
  * schema: {
49
52
  * type: "object",
50
53
  * properties: {
51
- * name: { type: "string" },
54
+ * name: { type: "string", minLength: 1 },
52
55
  * age: { type: "number", minimum: 0 }
53
56
  * },
54
57
  * required: ["name"]
55
58
  * }
56
59
  * });
57
- *
58
- * console.log(`Schema created with ID: ${result.schemaId}`);
60
+ * console.log(`Schema ${result.schemaId} at ${result.definitionUrl}`);
59
61
  * ```
60
62
  */
61
63
  async create(params) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/controllers/schemas.ts"],"sourcesContent":["import type {\n Schema,\n SchemaMetadata,\n CompleteSchema,\n AddSchemaParams,\n} from \"../types/index\";\n// import type { TransactionResult } from \"../types/operations\";\nimport type { SchemaAddedResult } from \"../types/transactionResults\";\nimport type { ControllerContext } from \"./permissions\";\nimport { BaseController } from \"./base\";\nimport { getContractAddress } from \"../config/addresses\";\nimport { getAbi } from \"../generated/abi\";\nimport { gasAwareMulticall } from \"../utils/multicall\";\nimport {\n validateDataSchemaAgainstMetaSchema,\n SchemaValidationError,\n type DataSchema,\n} from \"../utils/schemaValidation\";\nimport {\n fetchSchemaFromChain,\n fetchSchemaCountFromChain,\n} from \"../utils/blockchain/registry\";\nimport {\n GetSchemaDocument,\n ListSchemasDocument,\n CountSchemasDocument,\n type GetSchemaQuery,\n type ListSchemasQuery,\n type CountSchemasQuery,\n} from \"../generated/subgraph\";\nimport { print } from \"graphql\";\nimport { fetchFromUrl, UrlResolutionError } from \"../utils/urlResolver\";\n\n/**\n * Parameters for creating a new schema with automatic IPFS upload.\n *\n * @remarks\n * This interface is used with the high-level `schemas.create()` method which\n * automatically uploads the schema definition to IPFS and registers it on-chain.\n * @category Schema Management\n */\nexport interface CreateSchemaParams {\n /** The name of the schema */\n name: string;\n /** The dialect of the schema (e.g., 'json' or 'sqlite') */\n dialect: \"json\" | \"sqlite\";\n /** The schema definition object or JSON string */\n schema: object | string;\n}\n\n/**\n * Result of creating a new schema.\n *\n * @remarks\n * Returned by the `schemas.create()` method after successful upload and registration.\n * @category Schema Management\n */\nexport interface CreateSchemaResult {\n /** The schema ID assigned by the contract */\n schemaId: bigint;\n /** The IPFS URL where the schema definition is stored */\n definitionUrl: string;\n /** The transaction hash of the schema registration */\n transactionHash: string;\n}\n\n/**\n * Manages data schemas and refiners on the Vana network.\n *\n * @remarks\n * This controller handles the complete lifecycle of data schemas including creation,\n * validation, IPFS upload, and blockchain registration. It provides methods for managing\n * both schemas (data structure definitions) and refiners (data processing definitions).\n *\n * **Schema Storage:**\n * Schemas are stored unencrypted on IPFS for public access and reusability across the network.\n * Schema definitions use JSON Schema format for data validation and structure definition.\n *\n * **Method Selection:**\n * - `create()` validates, uploads to IPFS, and registers new schemas on blockchain\n * - `get()` retrieves existing schema metadata by ID from blockchain contracts\n * - `count()` returns total number of registered schemas for pagination\n * - `list()` provides paginated access to all schemas with optional filtering\n * - `addSchema()` provides lower-level schema registration with pre-uploaded URLs\n *\n * **Storage Requirements:**\n * Methods requiring storage configuration: `create()`\n * Methods working without storage: `get()`, `count()`, `list()`, `addSchema()`\n *\n * @example\n * ```typescript\n * // Create a new schema with automatic IPFS upload\n * const result = await vana.schemas.create({\n * name: \"User Profile\",\n * dialect: \"json\",\n * schema: {\n * type: \"object\",\n * properties: {\n * name: { type: \"string\" },\n * age: { type: \"number\" }\n * },\n * required: [\"name\"]\n * }\n * });\n *\n * // Get an existing schema\n * const schema = await vana.schemas.get(1);\n *\n * // List all schemas\n * const count = await vana.schemas.count();\n * ```\n * @category Schema Management\n */\nexport class SchemaController extends BaseController {\n constructor(context: ControllerContext) {\n super(context);\n }\n\n /**\n * Creates a new schema with automatic validation and IPFS upload.\n *\n * @remarks\n * This is the primary method for creating schemas on the Vana network. It handles\n * the complete workflow including schema validation, IPFS upload, and blockchain\n * registration. The schema definition is stored unencrypted on IPFS to enable\n * public access and reusability.\n *\n * The method automatically:\n * - Validates the schema definition against the Vana metaschema\n * - Uploads the definition to IPFS to generate a permanent URL\n * - Registers the schema on the blockchain with the generated URL\n *\n * @param params - Schema creation parameters including name, dialect, and definition\n * @returns Promise resolving to creation results with schema ID and transaction hash\n * @throws {SchemaValidationError} When the schema definition is invalid\n * @throws {Error} When IPFS upload or blockchain registration fails\n * @example\n * ```typescript\n * // Create a JSON schema for user profiles\n * const result = await vana.schemas.create({\n * name: \"User Profile\",\n * dialect: \"json\",\n * schema: {\n * type: \"object\",\n * properties: {\n * name: { type: \"string\" },\n * age: { type: \"number\", minimum: 0 }\n * },\n * required: [\"name\"]\n * }\n * });\n *\n * console.log(`Schema created with ID: ${result.schemaId}`);\n * ```\n */\n async create(params: CreateSchemaParams): Promise<CreateSchemaResult> {\n this.assertWallet();\n const { name, dialect, schema } = params;\n\n try {\n // Step 1: Normalize and validate the schema definition\n let schemaDefinition: object;\n if (typeof schema === \"string\") {\n try {\n schemaDefinition = JSON.parse(schema);\n } catch {\n throw new SchemaValidationError(\n \"Invalid JSON in schema definition\",\n [],\n );\n }\n } else {\n schemaDefinition = schema;\n }\n\n // Step 2: Validate against metaschema\n const dataSchema: DataSchema = {\n name,\n version: \"1.0.0\",\n dialect,\n schema: schemaDefinition,\n };\n\n validateDataSchemaAgainstMetaSchema(dataSchema);\n\n // Step 3: Upload to IPFS (unencrypted for public access)\n if (!this.context.storageManager) {\n // Use centralized validation if available, otherwise fall back to old behavior\n if (this.context.validateStorageRequired) {\n this.context.validateStorageRequired();\n // The validateStorageRequired method throws, so this line should never be reached\n // but TypeScript doesn't know that, so we need this fallback\n throw new Error(\"Storage validation failed\");\n } else {\n throw new Error(\n \"Storage manager not configured. Please provide storage providers in VanaConfig.\",\n );\n }\n }\n\n const schemaBlob = new Blob([JSON.stringify(dataSchema)], {\n type: \"application/json\",\n });\n\n const uploadResult = await this.context.storageManager.upload(\n schemaBlob,\n `${name.replace(/[^a-zA-Z0-9]/g, \"_\")}.json`,\n \"ipfs\", // Use IPFS for public schema storage\n );\n\n // Step 4: Register on blockchain\n const chainId =\n this.context.walletClient?.chain?.id ??\n this.context.publicClient.chain?.id;\n if (!chainId) {\n throw new Error(\"Chain ID not available\");\n }\n\n const dataRefinerRegistryAddress = getContractAddress(\n chainId,\n \"DataRefinerRegistry\",\n );\n const dataRefinerRegistryAbi = getAbi(\"DataRefinerRegistry\");\n\n const account =\n this.context.walletClient.account ?? this.context.userAddress;\n const from = typeof account === \"string\" ? account : account?.address;\n\n const hash = await this.context.walletClient.writeContract({\n address: dataRefinerRegistryAddress,\n abi: dataRefinerRegistryAbi,\n functionName: \"addSchema\",\n args: [name, dialect, uploadResult.url],\n account,\n chain: this.context.walletClient.chain ?? null,\n });\n\n const { tx } = await import(\"../utils/transactionHelpers\");\n const txResult = tx({\n hash,\n from: from!,\n contract: \"DataRefinerRegistry\",\n fn: \"addSchema\",\n });\n\n // Wait for events and extract domain data\n if (!this.context.waitForTransactionEvents) {\n throw new Error(\"waitForTransactionEvents not configured\");\n }\n\n const result = await this.context.waitForTransactionEvents(txResult);\n const event = result.expectedEvents.SchemaAdded;\n if (!event) {\n throw new Error(\"SchemaAdded event not found in transaction\");\n }\n\n return {\n schemaId: event.schemaId,\n definitionUrl: uploadResult.url,\n transactionHash: hash,\n };\n } catch (error) {\n if (error instanceof SchemaValidationError) {\n throw error;\n }\n throw new Error(\n `Schema creation failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Retrieves a complete schema by its ID with definition fetched and flattened.\n *\n * @param schemaId - The ID of the schema to retrieve\n * @param options - Optional parameters\n * @param options.subgraphUrl - Custom subgraph URL to use instead of default\n * @returns Promise resolving to the complete schema object with all fields populated\n * @throws {Error} When the schema is not found, definition cannot be fetched, or chain is unavailable\n * @example\n * ```typescript\n * const schema = await vana.schemas.get(1);\n * console.log(`Schema: ${schema.name} (${schema.dialect})`);\n * console.log(`Version: ${schema.version}`);\n * console.log(`Description: ${schema.description}`);\n * console.log('Schema:', schema.schema);\n *\n * // Use directly with validator (schema has all required fields)\n * validator.validateDataAgainstSchema(data, schema);\n * ```\n */\n async get(\n schemaId: number,\n options: { subgraphUrl?: string } = {},\n ): Promise<CompleteSchema> {\n const subgraphUrl = options.subgraphUrl ?? this.context.subgraphUrl;\n\n let metadata: SchemaMetadata;\n\n // Try subgraph first if available\n if (subgraphUrl) {\n try {\n metadata = await this._getSchemaViaSubgraph({ schemaId, subgraphUrl });\n } catch (error) {\n console.debug(\"Subgraph query failed, falling back to RPC:\", error);\n // Fall through to RPC\n try {\n metadata = await fetchSchemaFromChain(this.context, schemaId);\n } catch (rpcError) {\n throw new Error(\n `Failed to get schema: ${rpcError instanceof Error ? rpcError.message : \"Unknown error\"}`,\n );\n }\n }\n } else {\n // Use RPC directly\n try {\n metadata = await fetchSchemaFromChain(this.context, schemaId);\n } catch (error) {\n throw new Error(\n `Failed to get schema: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n // Fetch the definition (should be a complete DataSchema)\n const definition = await fetchFromUrl(\n metadata.definitionUrl,\n this.context.downloadRelayer,\n );\n\n if (!definition || typeof definition !== \"object\") {\n throw new Error(\n `Invalid schema definition format for schema ${schemaId}`,\n );\n }\n\n // Validate the fetched DataSchema\n validateDataSchemaAgainstMetaSchema(definition);\n const dataSchema = definition as DataSchema;\n\n // Verify on-chain and off-chain data match\n if (dataSchema.name !== metadata.name) {\n console.warn(\n `Schema name mismatch for ID ${schemaId}: on-chain=\"${metadata.name}\" off-chain=\"${dataSchema.name}\" (using on-chain value)`,\n );\n }\n if (dataSchema.dialect !== metadata.dialect) {\n console.warn(\n `Schema dialect mismatch for ID ${schemaId}: on-chain=\"${metadata.dialect}\" off-chain=\"${dataSchema.dialect}\" (using on-chain value)`,\n );\n }\n\n // Return using on-chain values as authoritative source\n return {\n ...metadata,\n version: dataSchema.version,\n description: dataSchema.description,\n schema: dataSchema.schema,\n };\n }\n\n /**\n * Gets the total number of schemas registered on the network.\n *\n * @param options - Optional parameters\n * @param options.subgraphUrl - Custom subgraph URL to use instead of default\n * @returns Promise resolving to the total schema count\n * @throws {Error} When the count cannot be retrieved\n * @example\n * ```typescript\n * const count = await vana.schemas.count();\n * console.log(`Total schemas: ${count}`);\n *\n * // With custom subgraph\n * const count = await vana.schemas.count({\n * subgraphUrl: 'https://custom-subgraph.com/graphql'\n * });\n * ```\n */\n async count(options: { subgraphUrl?: string } = {}): Promise<number> {\n const subgraphUrl = options.subgraphUrl ?? this.context.subgraphUrl;\n\n // Try subgraph first if available\n if (subgraphUrl) {\n try {\n return await this._countSchemasViaSubgraph({ subgraphUrl });\n } catch (error) {\n console.debug(\"Subgraph query failed, falling back to RPC:\", error);\n // Fall through to RPC\n }\n }\n\n // Use RPC (as fallback or primary method)\n try {\n return await fetchSchemaCountFromChain(this.context);\n } catch (error) {\n throw new Error(\n `Failed to get schemas count: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Lists all schemas with pagination.\n *\n * @param options - Optional parameters for listing schemas\n * @param options.limit - Maximum number of schemas to return\n * @param options.offset - Number of schemas to skip\n * @param options.subgraphUrl - Custom subgraph URL to use instead of default\n * @param options.includeDefinitions - Whether to fetch and include schema definitions (default: false for performance)\n * @returns Promise resolving to an array of schemas\n * @example\n * ```typescript\n * // Get all schemas (without definitions for performance)\n * const schemas = await vana.schemas.list();\n *\n * // Get schemas with definitions\n * const schemas = await vana.schemas.list({ includeDefinitions: true });\n *\n * // Get schemas with pagination\n * const schemas = await vana.schemas.list({ limit: 10, offset: 0 });\n * ```\n */\n async list(\n options: {\n limit?: number;\n offset?: number;\n subgraphUrl?: string;\n includeDefinitions?: boolean;\n } = {},\n ): Promise<Schema[]> {\n const { limit = 100, offset = 0, includeDefinitions = false } = options;\n const subgraphUrl = options.subgraphUrl ?? this.context.subgraphUrl;\n\n // Try subgraph first if available\n if (subgraphUrl) {\n try {\n return await this._listSchemasViaSubgraph({\n limit,\n offset,\n subgraphUrl,\n });\n } catch (error) {\n console.debug(\"Subgraph query failed, falling back to RPC:\", error);\n // Fall through to RPC\n }\n }\n\n try {\n const totalCount = await this.count();\n const start = offset;\n const end = Math.min(start + limit, totalCount);\n\n if (end <= start) {\n return [];\n }\n\n // Get contract address and ABI\n const chainId =\n this.context.walletClient?.chain?.id ??\n this.context.publicClient.chain?.id;\n if (!chainId) {\n throw new Error(\"Chain ID not available\");\n }\n const dataRefinerRegistryAddress = getContractAddress(\n chainId,\n \"DataRefinerRegistry\",\n );\n const dataRefinerRegistryAbi = getAbi(\"DataRefinerRegistry\");\n\n // Build multicall batch for fetching schemas\n const schemaCalls = [];\n for (let i = start; i < end; i++) {\n schemaCalls.push({\n address: dataRefinerRegistryAddress,\n abi: dataRefinerRegistryAbi,\n functionName: \"schemas\",\n args: [BigInt(i + 1)], // Schema IDs are 1-based\n } as const);\n }\n\n // Fetch all schemas in batches using gasAwareMulticall\n const schemaResults = await gasAwareMulticall<\n typeof schemaCalls,\n true // Allow failures for individual schema lookups\n >(this.context.publicClient, {\n contracts: schemaCalls,\n allowFailure: true,\n });\n\n // Process results\n const schemas: Schema[] = [];\n schemaResults.forEach((result, index) => {\n if (result.status === \"success\" && result.result) {\n const schemaId = start + index + 1; // Schema IDs are 1-based\n const schemaData = result.result as {\n name: string;\n dialect: string;\n definitionUrl: string;\n };\n\n if (\n schemaData.name &&\n schemaData.dialect &&\n schemaData.definitionUrl\n ) {\n schemas.push({\n id: schemaId,\n name: schemaData.name,\n dialect: schemaData.dialect as \"json\" | \"sqlite\",\n definitionUrl: schemaData.definitionUrl,\n });\n } else {\n console.warn(`Incomplete schema data for ID ${schemaId}`);\n }\n } else {\n // Skip schemas that can't be retrieved\n console.warn(`Failed to retrieve schema ${start + index + 1}`);\n }\n });\n\n // Optionally fetch definitions for all schemas\n if (includeDefinitions) {\n await this._fetchDefinitionsForSchemas(schemas);\n }\n\n return schemas;\n } catch (error) {\n throw new Error(\n `Failed to list schemas: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Adds a schema using the legacy method (low-level API).\n *\n * @deprecated Use create() instead for the high-level API with automatic IPFS upload\n * @param params - Schema parameters including pre-generated definition URL\n * @returns Promise resolving to the add schema result\n */\n async addSchema(params: AddSchemaParams): Promise<SchemaAddedResult> {\n this.assertWallet();\n try {\n const chainId =\n this.context.walletClient?.chain?.id ??\n this.context.publicClient.chain?.id;\n if (!chainId) {\n throw new Error(\"Chain ID not available\");\n }\n\n const dataRefinerRegistryAddress = getContractAddress(\n chainId,\n \"DataRefinerRegistry\",\n );\n const dataRefinerRegistryAbi = getAbi(\"DataRefinerRegistry\");\n\n const account =\n this.context.walletClient.account ?? this.context.userAddress;\n const from = typeof account === \"string\" ? account : account?.address;\n\n const hash = await this.context.walletClient.writeContract({\n address: dataRefinerRegistryAddress,\n abi: dataRefinerRegistryAbi,\n functionName: \"addSchema\",\n args: [params.name, params.dialect, params.definitionUrl],\n account,\n chain: this.context.walletClient.chain ?? null,\n });\n\n // Create TransactionResult POJO\n const { tx } = await import(\"../utils/transactionHelpers\");\n const txResult = tx({\n hash,\n from: from!,\n contract: \"DataRefinerRegistry\",\n fn: \"addSchema\",\n });\n\n // Wait for events and extract domain data\n if (!this.context.waitForTransactionEvents) {\n throw new Error(\"waitForTransactionEvents not configured\");\n }\n\n const result = await this.context.waitForTransactionEvents(txResult);\n const event = result.expectedEvents.SchemaAdded;\n if (!event) {\n throw new Error(\"SchemaAdded event not found in transaction\");\n }\n\n const receipt = await this.context.publicClient.getTransactionReceipt({\n hash,\n });\n\n return {\n transactionHash: hash,\n blockNumber: receipt.blockNumber,\n gasUsed: receipt.gasUsed,\n schemaId: event.schemaId,\n name: event.name,\n dialect: event.dialect,\n definitionUrl: event.definitionUrl,\n };\n } catch (error) {\n throw new Error(\n `Failed to add schema: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Internal method: Query schema via subgraph\n *\n * @param params - Query parameters\n * @param params.schemaId - The ID of the schema to retrieve\n * @param params.subgraphUrl - The subgraph URL to query\n * @returns Promise resolving to the schema object\n * @private\n */\n private async _getSchemaViaSubgraph(params: {\n schemaId: number;\n subgraphUrl: string;\n }): Promise<SchemaMetadata> {\n const { schemaId, subgraphUrl } = params;\n\n const response = await fetch(subgraphUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n query: print(GetSchemaDocument),\n variables: { id: schemaId.toString() },\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Subgraph request failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = (await response.json()) as {\n data?: GetSchemaQuery;\n errors?: { message: string }[];\n };\n\n if (result.errors) {\n throw new Error(\n `Subgraph query errors: ${result.errors.map((e) => e.message).join(\", \")}`,\n );\n }\n\n if (!result.data?.schema) {\n throw new Error(`Schema ${schemaId} not found in subgraph`);\n }\n\n // Map subgraph schema to SDK schema type\n const subgraphSchema = result.data.schema;\n return {\n id: parseInt(subgraphSchema.id),\n name: subgraphSchema.name,\n dialect: subgraphSchema.dialect as \"json\" | \"sqlite\",\n definitionUrl: subgraphSchema.definitionUrl,\n };\n }\n\n /**\n * Internal method: List schemas via subgraph\n *\n * @param params - Query parameters\n * @param params.limit - Maximum number of schemas to return\n * @param params.offset - Number of schemas to skip\n * @param params.subgraphUrl - The subgraph URL to query\n * @returns Promise resolving to an array of schemas\n * @private\n */\n private async _listSchemasViaSubgraph(params: {\n limit: number;\n offset: number;\n subgraphUrl: string;\n }): Promise<Schema[]> {\n const { limit, offset, subgraphUrl } = params;\n\n const response = await fetch(subgraphUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n query: print(ListSchemasDocument),\n variables: { first: limit, skip: offset },\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Subgraph request failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = (await response.json()) as {\n data?: ListSchemasQuery;\n errors?: { message: string }[];\n };\n\n if (result.errors) {\n throw new Error(\n `Subgraph query errors: ${result.errors.map((e) => e.message).join(\", \")}`,\n );\n }\n\n if (!result.data?.schemas) {\n return [];\n }\n\n // Map subgraph schemas to SDK schema type\n const schemas = result.data.schemas.map((schema) => ({\n id: parseInt(schema.id),\n name: schema.name,\n dialect: schema.dialect as \"json\" | \"sqlite\",\n definitionUrl: schema.definitionUrl,\n }));\n\n // Optionally fetch definitions if requested\n const { includeDefinitions } = params as { includeDefinitions?: boolean };\n if (includeDefinitions) {\n await this._fetchDefinitionsForSchemas(schemas);\n }\n\n return schemas;\n }\n\n /**\n * Internal method: Count schemas via subgraph\n *\n * @param params - Query parameters\n * @param params.subgraphUrl - The subgraph URL to query\n * @returns Promise resolving to the total schema count\n * @private\n */\n private async _countSchemasViaSubgraph(params: {\n subgraphUrl: string;\n }): Promise<number> {\n const { subgraphUrl } = params;\n\n const response = await fetch(subgraphUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n query: print(CountSchemasDocument),\n variables: {},\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Subgraph request failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = (await response.json()) as {\n data?: CountSchemasQuery;\n errors?: { message: string }[];\n };\n\n if (result.errors) {\n throw new Error(\n `Subgraph query errors: ${result.errors.map((e) => e.message).join(\", \")}`,\n );\n }\n\n return result.data?.schemas?.length ?? 0;\n }\n\n /**\n * Gets the user's wallet address.\n *\n * @private\n * @returns Promise resolving to the user's address\n */\n\n /**\n * Fetches and attaches definitions to an array of schemas.\n *\n * @param schemas - Array of schemas to fetch definitions for\n * @private\n */\n private async _fetchDefinitionsForSchemas(schemas: Schema[]): Promise<void> {\n // Fetch definitions concurrently for performance\n await Promise.all(\n schemas.map(async (schema) => {\n if (!schema.definitionUrl) return;\n\n try {\n const definition = await fetchFromUrl(\n schema.definitionUrl,\n this.context.downloadRelayer,\n );\n\n if (definition && typeof definition === \"object\") {\n // Validate the fetched DataSchema\n validateDataSchemaAgainstMetaSchema(definition);\n const dataSchema = definition as DataSchema;\n\n // Populate flat fields\n schema.version = dataSchema.version;\n schema.description = dataSchema.description;\n schema.schema = dataSchema.schema;\n }\n } catch (error) {\n // Don't fail the entire list operation if one definition fails\n console.error(\n `Failed to fetch/validate definition for schema ${schema.id}:`,\n error instanceof UrlResolutionError ||\n error instanceof SchemaValidationError\n ? error.message\n : error,\n );\n }\n }),\n );\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/controllers/schemas.ts"],"sourcesContent":["import type {\n Schema,\n SchemaMetadata,\n CompleteSchema,\n AddSchemaParams,\n} from \"../types/index\";\n// import type { TransactionResult } from \"../types/operations\";\nimport type { SchemaAddedResult } from \"../types/transactionResults\";\nimport type { ControllerContext } from \"./permissions\";\nimport { BaseController } from \"./base\";\nimport { getContractAddress } from \"../config/addresses\";\nimport { getAbi } from \"../generated/abi\";\nimport { gasAwareMulticall } from \"../utils/multicall\";\nimport {\n validateDataSchemaAgainstMetaSchema,\n SchemaValidationError,\n type DataSchema,\n} from \"../utils/schemaValidation\";\nimport {\n fetchSchemaFromChain,\n fetchSchemaCountFromChain,\n} from \"../utils/blockchain/registry\";\nimport {\n GetSchemaDocument,\n ListSchemasDocument,\n CountSchemasDocument,\n type GetSchemaQuery,\n type ListSchemasQuery,\n type CountSchemasQuery,\n} from \"../generated/subgraph\";\nimport { print } from \"graphql\";\nimport { fetchFromUrl, UrlResolutionError } from \"../utils/urlResolver\";\n\n/**\n * Parameters for creating a new schema with automatic IPFS upload.\n *\n * @remarks\n * This interface is used with the high-level `schemas.create()` method which\n * automatically uploads the schema definition to IPFS and registers it on-chain.\n * @category Schema Management\n */\nexport interface CreateSchemaParams {\n /** The name of the schema */\n name: string;\n /** The dialect of the schema (e.g., 'json' or 'sqlite') */\n dialect: \"json\" | \"sqlite\";\n /** The schema definition object or JSON string */\n schema: object | string;\n}\n\n/**\n * Result of creating a new schema.\n *\n * @remarks\n * Returned by the `schemas.create()` method after successful upload and registration.\n * @category Schema Management\n */\nexport interface CreateSchemaResult {\n /** The schema ID assigned by the contract */\n schemaId: bigint;\n /** The IPFS URL where the schema definition is stored */\n definitionUrl: string;\n /** The transaction hash of the schema registration */\n transactionHash: string;\n}\n\n/**\n * Manages data schemas for validation and structure definition on Vana.\n *\n * @remarks\n * Handles schema lifecycle from creation through registration. Schemas define\n * data structure and validation rules, ensuring consistency across the network.\n * Stored unencrypted on IPFS for public reusability.\n *\n * **Architecture:**\n * Schemas use dual storage: definitions on IPFS (public), metadata on blockchain.\n * Supports JSON Schema and SQLite dialects for flexible data modeling.\n *\n * **Method Selection:**\n * - `create()` - Validate, upload to IPFS, register on blockchain\n * - `get()` - Retrieve schema with definition by ID\n * - `list()` - Paginated schema browsing with metadata\n * - `count()` - Total schemas for pagination\n * - `addSchema()` - Low-level registration with pre-uploaded URL\n *\n * **Storage Requirements:**\n * - Methods requiring storage: `create()`\n * - Methods without storage: `get()`, `list()`, `count()`, `addSchema()`\n *\n * @example\n * ```typescript\n * // Create schema with validation rules\n * const result = await vana.schemas.create({\n * name: \"User Profile\",\n * dialect: \"json\",\n * schema: {\n * type: \"object\",\n * properties: {\n * name: { type: \"string\", minLength: 1 },\n * age: { type: \"number\", minimum: 0, maximum: 150 }\n * },\n * required: [\"name\"]\n * }\n * });\n * console.log(`Schema ${result.schemaId} created`);\n *\n * // Retrieve for validation\n * const schema = await vana.schemas.get(result.schemaId);\n * console.log(`Schema: ${schema.name} (${schema.dialect})`);\n *\n * // Browse available schemas\n * const schemas = await vana.schemas.list({ limit: 10 });\n * schemas.forEach(s => console.log(`${s.id}: ${s.name}`));\n * ```\n *\n * @category Schema Management\n * @see For conceptual overview, visit {@link https://docs.vana.org/docs/schemas}\n */\nexport class SchemaController extends BaseController {\n constructor(context: ControllerContext) {\n super(context);\n }\n\n /**\n * Creates a schema with validation and IPFS upload.\n *\n * @remarks\n * Primary method for schema creation. Validates definition,\n * uploads to IPFS (unencrypted for reusability), and registers\n * on blockchain. Schema becomes immediately available network-wide.\n *\n * @param params - Creation configuration\n * @param params.name - Human-readable schema name\n * @param params.dialect - Schema format (`\"json\"` or `\"sqlite\"`)\n * @param params.schema - Definition object or JSON string\n *\n * @returns Schema ID, IPFS URL, and transaction hash\n *\n * @throws {SchemaValidationError} Invalid schema definition.\n * Verify schema follows JSON Schema or SQLite format.\n * @throws {Error} Storage not configured.\n * Configure storage providers in VanaConfig.\n * @throws {Error} IPFS upload failed.\n * Check network and storage provider status.\n *\n * @example\n * ```typescript\n * const result = await vana.schemas.create({\n * name: \"User Profile\",\n * dialect: \"json\",\n * schema: {\n * type: \"object\",\n * properties: {\n * name: { type: \"string\", minLength: 1 },\n * age: { type: \"number\", minimum: 0 }\n * },\n * required: [\"name\"]\n * }\n * });\n * console.log(`Schema ${result.schemaId} at ${result.definitionUrl}`);\n * ```\n */\n async create(params: CreateSchemaParams): Promise<CreateSchemaResult> {\n this.assertWallet();\n const { name, dialect, schema } = params;\n\n try {\n // Step 1: Normalize and validate the schema definition\n let schemaDefinition: object;\n if (typeof schema === \"string\") {\n try {\n schemaDefinition = JSON.parse(schema);\n } catch {\n throw new SchemaValidationError(\n \"Invalid JSON in schema definition\",\n [],\n );\n }\n } else {\n schemaDefinition = schema;\n }\n\n // Step 2: Validate against metaschema\n const dataSchema: DataSchema = {\n name,\n version: \"1.0.0\",\n dialect,\n schema: schemaDefinition,\n };\n\n validateDataSchemaAgainstMetaSchema(dataSchema);\n\n // Step 3: Upload to IPFS (unencrypted for public access)\n if (!this.context.storageManager) {\n // Use centralized validation if available, otherwise fall back to old behavior\n if (this.context.validateStorageRequired) {\n this.context.validateStorageRequired();\n // The validateStorageRequired method throws, so this line should never be reached\n // but TypeScript doesn't know that, so we need this fallback\n throw new Error(\"Storage validation failed\");\n } else {\n throw new Error(\n \"Storage manager not configured. Please provide storage providers in VanaConfig.\",\n );\n }\n }\n\n const schemaBlob = new Blob([JSON.stringify(dataSchema)], {\n type: \"application/json\",\n });\n\n const uploadResult = await this.context.storageManager.upload(\n schemaBlob,\n `${name.replace(/[^a-zA-Z0-9]/g, \"_\")}.json`,\n \"ipfs\", // Use IPFS for public schema storage\n );\n\n // Step 4: Register on blockchain\n const chainId =\n this.context.walletClient?.chain?.id ??\n this.context.publicClient.chain?.id;\n if (!chainId) {\n throw new Error(\"Chain ID not available\");\n }\n\n const dataRefinerRegistryAddress = getContractAddress(\n chainId,\n \"DataRefinerRegistry\",\n );\n const dataRefinerRegistryAbi = getAbi(\"DataRefinerRegistry\");\n\n const account =\n this.context.walletClient.account ?? this.context.userAddress;\n const from = typeof account === \"string\" ? account : account?.address;\n\n const hash = await this.context.walletClient.writeContract({\n address: dataRefinerRegistryAddress,\n abi: dataRefinerRegistryAbi,\n functionName: \"addSchema\",\n args: [name, dialect, uploadResult.url],\n account,\n chain: this.context.walletClient.chain ?? null,\n });\n\n const { tx } = await import(\"../utils/transactionHelpers\");\n const txResult = tx({\n hash,\n from: from!,\n contract: \"DataRefinerRegistry\",\n fn: \"addSchema\",\n });\n\n // Wait for events and extract domain data\n if (!this.context.waitForTransactionEvents) {\n throw new Error(\"waitForTransactionEvents not configured\");\n }\n\n const result = await this.context.waitForTransactionEvents(txResult);\n const event = result.expectedEvents.SchemaAdded;\n if (!event) {\n throw new Error(\"SchemaAdded event not found in transaction\");\n }\n\n return {\n schemaId: event.schemaId,\n definitionUrl: uploadResult.url,\n transactionHash: hash,\n };\n } catch (error) {\n if (error instanceof SchemaValidationError) {\n throw error;\n }\n throw new Error(\n `Schema creation failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Retrieves a complete schema by its ID with definition fetched and flattened.\n *\n * @param schemaId - The ID of the schema to retrieve\n * @param options - Optional parameters\n * @param options.subgraphUrl - Custom subgraph URL to use instead of default\n * @returns Promise resolving to the complete schema object with all fields populated\n * @throws {Error} When the schema is not found, definition cannot be fetched, or chain is unavailable\n * @example\n * ```typescript\n * const schema = await vana.schemas.get(1);\n * console.log(`Schema: ${schema.name} (${schema.dialect})`);\n * console.log(`Version: ${schema.version}`);\n * console.log(`Description: ${schema.description}`);\n * console.log('Schema:', schema.schema);\n *\n * // Use directly with validator (schema has all required fields)\n * validator.validateDataAgainstSchema(data, schema);\n * ```\n */\n async get(\n schemaId: number,\n options: { subgraphUrl?: string } = {},\n ): Promise<CompleteSchema> {\n const subgraphUrl = options.subgraphUrl ?? this.context.subgraphUrl;\n\n let metadata: SchemaMetadata;\n\n // Try subgraph first if available\n if (subgraphUrl) {\n try {\n metadata = await this._getSchemaViaSubgraph({ schemaId, subgraphUrl });\n } catch (error) {\n console.debug(\"Subgraph query failed, falling back to RPC:\", error);\n // Fall through to RPC\n try {\n metadata = await fetchSchemaFromChain(this.context, schemaId);\n } catch (rpcError) {\n throw new Error(\n `Failed to get schema: ${rpcError instanceof Error ? rpcError.message : \"Unknown error\"}`,\n );\n }\n }\n } else {\n // Use RPC directly\n try {\n metadata = await fetchSchemaFromChain(this.context, schemaId);\n } catch (error) {\n throw new Error(\n `Failed to get schema: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n // Fetch the definition (should be a complete DataSchema)\n const definition = await fetchFromUrl(\n metadata.definitionUrl,\n this.context.downloadRelayer,\n );\n\n if (!definition || typeof definition !== \"object\") {\n throw new Error(\n `Invalid schema definition format for schema ${schemaId}`,\n );\n }\n\n // Validate the fetched DataSchema\n validateDataSchemaAgainstMetaSchema(definition);\n const dataSchema = definition as DataSchema;\n\n // Verify on-chain and off-chain data match\n if (dataSchema.name !== metadata.name) {\n console.warn(\n `Schema name mismatch for ID ${schemaId}: on-chain=\"${metadata.name}\" off-chain=\"${dataSchema.name}\" (using on-chain value)`,\n );\n }\n if (dataSchema.dialect !== metadata.dialect) {\n console.warn(\n `Schema dialect mismatch for ID ${schemaId}: on-chain=\"${metadata.dialect}\" off-chain=\"${dataSchema.dialect}\" (using on-chain value)`,\n );\n }\n\n // Return using on-chain values as authoritative source\n return {\n ...metadata,\n version: dataSchema.version,\n description: dataSchema.description,\n schema: dataSchema.schema,\n };\n }\n\n /**\n * Gets the total number of schemas registered on the network.\n *\n * @param options - Optional parameters\n * @param options.subgraphUrl - Custom subgraph URL to use instead of default\n * @returns Promise resolving to the total schema count\n * @throws {Error} When the count cannot be retrieved\n * @example\n * ```typescript\n * const count = await vana.schemas.count();\n * console.log(`Total schemas: ${count}`);\n *\n * // With custom subgraph\n * const count = await vana.schemas.count({\n * subgraphUrl: 'https://custom-subgraph.com/graphql'\n * });\n * ```\n */\n async count(options: { subgraphUrl?: string } = {}): Promise<number> {\n const subgraphUrl = options.subgraphUrl ?? this.context.subgraphUrl;\n\n // Try subgraph first if available\n if (subgraphUrl) {\n try {\n return await this._countSchemasViaSubgraph({ subgraphUrl });\n } catch (error) {\n console.debug(\"Subgraph query failed, falling back to RPC:\", error);\n // Fall through to RPC\n }\n }\n\n // Use RPC (as fallback or primary method)\n try {\n return await fetchSchemaCountFromChain(this.context);\n } catch (error) {\n throw new Error(\n `Failed to get schemas count: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Lists all schemas with pagination.\n *\n * @param options - Optional parameters for listing schemas\n * @param options.limit - Maximum number of schemas to return\n * @param options.offset - Number of schemas to skip\n * @param options.subgraphUrl - Custom subgraph URL to use instead of default\n * @param options.includeDefinitions - Whether to fetch and include schema definitions (default: false for performance)\n * @returns Promise resolving to an array of schemas\n * @example\n * ```typescript\n * // Get all schemas (without definitions for performance)\n * const schemas = await vana.schemas.list();\n *\n * // Get schemas with definitions\n * const schemas = await vana.schemas.list({ includeDefinitions: true });\n *\n * // Get schemas with pagination\n * const schemas = await vana.schemas.list({ limit: 10, offset: 0 });\n * ```\n */\n async list(\n options: {\n limit?: number;\n offset?: number;\n subgraphUrl?: string;\n includeDefinitions?: boolean;\n } = {},\n ): Promise<Schema[]> {\n const { limit = 100, offset = 0, includeDefinitions = false } = options;\n const subgraphUrl = options.subgraphUrl ?? this.context.subgraphUrl;\n\n // Try subgraph first if available\n if (subgraphUrl) {\n try {\n return await this._listSchemasViaSubgraph({\n limit,\n offset,\n subgraphUrl,\n });\n } catch (error) {\n console.debug(\"Subgraph query failed, falling back to RPC:\", error);\n // Fall through to RPC\n }\n }\n\n try {\n const totalCount = await this.count();\n const start = offset;\n const end = Math.min(start + limit, totalCount);\n\n if (end <= start) {\n return [];\n }\n\n // Get contract address and ABI\n const chainId =\n this.context.walletClient?.chain?.id ??\n this.context.publicClient.chain?.id;\n if (!chainId) {\n throw new Error(\"Chain ID not available\");\n }\n const dataRefinerRegistryAddress = getContractAddress(\n chainId,\n \"DataRefinerRegistry\",\n );\n const dataRefinerRegistryAbi = getAbi(\"DataRefinerRegistry\");\n\n // Build multicall batch for fetching schemas\n const schemaCalls = [];\n for (let i = start; i < end; i++) {\n schemaCalls.push({\n address: dataRefinerRegistryAddress,\n abi: dataRefinerRegistryAbi,\n functionName: \"schemas\",\n args: [BigInt(i + 1)], // Schema IDs are 1-based\n } as const);\n }\n\n // Fetch all schemas in batches using gasAwareMulticall\n const schemaResults = await gasAwareMulticall<\n typeof schemaCalls,\n true // Allow failures for individual schema lookups\n >(this.context.publicClient, {\n contracts: schemaCalls,\n allowFailure: true,\n });\n\n // Process results\n const schemas: Schema[] = [];\n schemaResults.forEach((result, index) => {\n if (result.status === \"success\" && result.result) {\n const schemaId = start + index + 1; // Schema IDs are 1-based\n const schemaData = result.result as {\n name: string;\n dialect: string;\n definitionUrl: string;\n };\n\n if (\n schemaData.name &&\n schemaData.dialect &&\n schemaData.definitionUrl\n ) {\n schemas.push({\n id: schemaId,\n name: schemaData.name,\n dialect: schemaData.dialect as \"json\" | \"sqlite\",\n definitionUrl: schemaData.definitionUrl,\n });\n } else {\n console.warn(`Incomplete schema data for ID ${schemaId}`);\n }\n } else {\n // Skip schemas that can't be retrieved\n console.warn(`Failed to retrieve schema ${start + index + 1}`);\n }\n });\n\n // Optionally fetch definitions for all schemas\n if (includeDefinitions) {\n await this._fetchDefinitionsForSchemas(schemas);\n }\n\n return schemas;\n } catch (error) {\n throw new Error(\n `Failed to list schemas: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Adds a schema using the legacy method (low-level API).\n *\n * @deprecated Use create() instead for the high-level API with automatic IPFS upload\n * @param params - Schema parameters including pre-generated definition URL\n * @returns Promise resolving to the add schema result\n */\n async addSchema(params: AddSchemaParams): Promise<SchemaAddedResult> {\n this.assertWallet();\n try {\n const chainId =\n this.context.walletClient?.chain?.id ??\n this.context.publicClient.chain?.id;\n if (!chainId) {\n throw new Error(\"Chain ID not available\");\n }\n\n const dataRefinerRegistryAddress = getContractAddress(\n chainId,\n \"DataRefinerRegistry\",\n );\n const dataRefinerRegistryAbi = getAbi(\"DataRefinerRegistry\");\n\n const account =\n this.context.walletClient.account ?? this.context.userAddress;\n const from = typeof account === \"string\" ? account : account?.address;\n\n const hash = await this.context.walletClient.writeContract({\n address: dataRefinerRegistryAddress,\n abi: dataRefinerRegistryAbi,\n functionName: \"addSchema\",\n args: [params.name, params.dialect, params.definitionUrl],\n account,\n chain: this.context.walletClient.chain ?? null,\n });\n\n // Create TransactionResult POJO\n const { tx } = await import(\"../utils/transactionHelpers\");\n const txResult = tx({\n hash,\n from: from!,\n contract: \"DataRefinerRegistry\",\n fn: \"addSchema\",\n });\n\n // Wait for events and extract domain data\n if (!this.context.waitForTransactionEvents) {\n throw new Error(\"waitForTransactionEvents not configured\");\n }\n\n const result = await this.context.waitForTransactionEvents(txResult);\n const event = result.expectedEvents.SchemaAdded;\n if (!event) {\n throw new Error(\"SchemaAdded event not found in transaction\");\n }\n\n const receipt = await this.context.publicClient.getTransactionReceipt({\n hash,\n });\n\n return {\n transactionHash: hash,\n blockNumber: receipt.blockNumber,\n gasUsed: receipt.gasUsed,\n schemaId: event.schemaId,\n name: event.name,\n dialect: event.dialect,\n definitionUrl: event.definitionUrl,\n };\n } catch (error) {\n throw new Error(\n `Failed to add schema: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Internal method: Query schema via subgraph\n *\n * @param params - Query parameters\n * @param params.schemaId - The ID of the schema to retrieve\n * @param params.subgraphUrl - The subgraph URL to query\n * @returns Promise resolving to the schema object\n * @private\n */\n private async _getSchemaViaSubgraph(params: {\n schemaId: number;\n subgraphUrl: string;\n }): Promise<SchemaMetadata> {\n const { schemaId, subgraphUrl } = params;\n\n const response = await fetch(subgraphUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n query: print(GetSchemaDocument),\n variables: { id: schemaId.toString() },\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Subgraph request failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = (await response.json()) as {\n data?: GetSchemaQuery;\n errors?: { message: string }[];\n };\n\n if (result.errors) {\n throw new Error(\n `Subgraph query errors: ${result.errors.map((e) => e.message).join(\", \")}`,\n );\n }\n\n if (!result.data?.schema) {\n throw new Error(`Schema ${schemaId} not found in subgraph`);\n }\n\n // Map subgraph schema to SDK schema type\n const subgraphSchema = result.data.schema;\n return {\n id: parseInt(subgraphSchema.id),\n name: subgraphSchema.name,\n dialect: subgraphSchema.dialect as \"json\" | \"sqlite\",\n definitionUrl: subgraphSchema.definitionUrl,\n };\n }\n\n /**\n * Internal method: List schemas via subgraph\n *\n * @param params - Query parameters\n * @param params.limit - Maximum number of schemas to return\n * @param params.offset - Number of schemas to skip\n * @param params.subgraphUrl - The subgraph URL to query\n * @returns Promise resolving to an array of schemas\n * @private\n */\n private async _listSchemasViaSubgraph(params: {\n limit: number;\n offset: number;\n subgraphUrl: string;\n }): Promise<Schema[]> {\n const { limit, offset, subgraphUrl } = params;\n\n const response = await fetch(subgraphUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n query: print(ListSchemasDocument),\n variables: { first: limit, skip: offset },\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Subgraph request failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = (await response.json()) as {\n data?: ListSchemasQuery;\n errors?: { message: string }[];\n };\n\n if (result.errors) {\n throw new Error(\n `Subgraph query errors: ${result.errors.map((e) => e.message).join(\", \")}`,\n );\n }\n\n if (!result.data?.schemas) {\n return [];\n }\n\n // Map subgraph schemas to SDK schema type\n const schemas = result.data.schemas.map((schema) => ({\n id: parseInt(schema.id),\n name: schema.name,\n dialect: schema.dialect as \"json\" | \"sqlite\",\n definitionUrl: schema.definitionUrl,\n }));\n\n // Optionally fetch definitions if requested\n const { includeDefinitions } = params as { includeDefinitions?: boolean };\n if (includeDefinitions) {\n await this._fetchDefinitionsForSchemas(schemas);\n }\n\n return schemas;\n }\n\n /**\n * Internal method: Count schemas via subgraph\n *\n * @param params - Query parameters\n * @param params.subgraphUrl - The subgraph URL to query\n * @returns Promise resolving to the total schema count\n * @private\n */\n private async _countSchemasViaSubgraph(params: {\n subgraphUrl: string;\n }): Promise<number> {\n const { subgraphUrl } = params;\n\n const response = await fetch(subgraphUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n query: print(CountSchemasDocument),\n variables: {},\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Subgraph request failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = (await response.json()) as {\n data?: CountSchemasQuery;\n errors?: { message: string }[];\n };\n\n if (result.errors) {\n throw new Error(\n `Subgraph query errors: ${result.errors.map((e) => e.message).join(\", \")}`,\n );\n }\n\n return result.data?.schemas?.length ?? 0;\n }\n\n /**\n * Gets the user's wallet address.\n *\n * @private\n * @returns Promise resolving to the user's address\n */\n\n /**\n * Fetches and attaches definitions to an array of schemas.\n *\n * @param schemas - Array of schemas to fetch definitions for\n * @private\n */\n private async _fetchDefinitionsForSchemas(schemas: Schema[]): Promise<void> {\n // Fetch definitions concurrently for performance\n await Promise.all(\n schemas.map(async (schema) => {\n if (!schema.definitionUrl) return;\n\n try {\n const definition = await fetchFromUrl(\n schema.definitionUrl,\n this.context.downloadRelayer,\n );\n\n if (definition && typeof definition === \"object\") {\n // Validate the fetched DataSchema\n validateDataSchemaAgainstMetaSchema(definition);\n const dataSchema = definition as DataSchema;\n\n // Populate flat fields\n schema.version = dataSchema.version;\n schema.description = dataSchema.description;\n schema.schema = dataSchema.schema;\n }\n } catch (error) {\n // Don't fail the entire list operation if one definition fails\n console.error(\n `Failed to fetch/validate definition for schema ${schema.id}:`,\n error instanceof UrlResolutionError ||\n error instanceof SchemaValidationError\n ? error.message\n : error,\n );\n }\n }),\n );\n }\n}\n"],"mappings":"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","names":[]}
@@ -36,23 +36,25 @@ class ServerController extends import_base.BaseController {
36
36
  return this.context.defaultPersonalServerUrl;
37
37
  }
38
38
  /**
39
- * Retrieves the cryptographic identity of a personal server.
39
+ * Retrieves cryptographic identity for a personal server.
40
40
  *
41
41
  * @remarks
42
- * This method fetches the public key and metadata for a personal server,
43
- * which is required for encrypting data before sharing with the server.
44
- * The identity includes the server's public key, address, and operational
45
- * details needed for secure communication. This information is cached
46
- * by identity servers to enable offline key retrieval.
42
+ * Fetches public key and metadata required for data encryption.
43
+ * Identity cached by infrastructure for offline retrieval.
44
+ * Each user address maps to deterministic server identity.
45
+ *
46
+ * @param request - Identity request parameters
47
+ * @param request.userAddress - Wallet address of server owner
48
+ *
49
+ * @returns Server identity with public key and metadata
50
+ *
51
+ * @throws {NetworkError} Identity service unavailable.
52
+ * Check network connection and server URL configuration.
53
+ * @throws {PersonalServerError} Identity retrieval failed.
54
+ * Verify user address and server registration.
47
55
  *
48
- * @param request - Parameters containing the user address
49
- * @param request.userAddress - The wallet address associated with the personal server
50
- * @returns Promise resolving to the server's identity information
51
- * @throws {NetworkError} When the identity service is unavailable or returns invalid data
52
- * @throws {PersonalServerError} When server identity cannot be retrieved
53
56
  * @example
54
57
  * ```typescript
55
- * // Get server identity for data encryption
56
58
  * const identity = await vana.server.getIdentity({
57
59
  * userAddress: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36"
58
60
  * });
@@ -61,9 +63,9 @@ class ServerController extends import_base.BaseController {
61
63
  * console.log(`Address: ${identity.address}`);
62
64
  * console.log(`Public Key: ${identity.publicKey}`);
63
65
  *
64
- * // Use the public key for encrypting data to share with this server
65
- * const encryptedData = await encryptWithWalletPublicKey(
66
- * userData,
66
+ * // Use for encryption before data sharing
67
+ * const encrypted = await encryptWithPublicKey(
68
+ * data,
67
69
  * identity.publicKey
68
70
  * );
69
71
  * ```
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/controllers/server.ts"],"sourcesContent":["import type {\n CreateOperationParams,\n InitPersonalServerParams,\n PersonalServerIdentity,\n} from \"../types\";\nimport type {\n CreateOperationResponse,\n GetOperationResponse,\n IdentityResponseModel,\n} from \"../generated/server/server-exports\";\nimport {\n NetworkError,\n SerializationError,\n SignatureError,\n PersonalServerError,\n} from \"../errors\";\nimport type { ControllerContext } from \"./permissions\";\nimport type { Operation, PollingOptions } from \"../types/operations\";\nimport { BaseController } from \"./base\";\n\n// Server types are now auto-imported from the generated exports\n\n/**\n * Manages interactions with Vana personal servers and identity infrastructure.\n *\n * @remarks\n * This controller handles communication with personal servers for data processing\n * and identity servers for public key derivation. It provides methods for posting\n * computation requests to personal servers, polling for results, and retrieving\n * cryptographic keys for secure data sharing. All server interactions use the\n * Replicate API infrastructure with proper authentication and error handling.\n *\n * **Server Identity System:**\n * Personal servers use deterministic key derivation: each user address maps to a specific server identity.\n * This enables secure communication without requiring servers to be online during key retrieval.\n *\n * **Method Selection:**\n * - `getIdentity()` retrieves server public keys and addresses for encryption setup\n * - `createOperation()` submits computation requests with signed permission verification\n * - `getOperation()` polls operation status and retrieves results when complete\n * - `cancelOperation()` stops running operations when cancellation is supported\n *\n * **Workflow Pattern:**\n * Typical flow: Get identity → Create operation → Poll status → Retrieve results\n *\n * @example\n * ```typescript\n * // Get a server's identity including public key for encryption\n * const identity = await vana.server.getIdentity({\n * userAddress: \"0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36\"\n * });\n *\n * // Create an operation using a granted permission\n * const response = await vana.server.createOperation({\n * permissionId: 123,\n * });\n *\n * // Poll for computation results\n * const result = await vana.server.getOperation(response.id);\n * ```\n * @category Server Management\n * @see {@link https://docs.vana.com/developer/personal-servers | Vana Personal Servers} for conceptual overview\n */\nexport class ServerController extends BaseController {\n constructor(context: ControllerContext) {\n super(context);\n }\n\n private get personalServerBaseUrl(): string {\n if (!this.context.defaultPersonalServerUrl) {\n throw new PersonalServerError(\n \"Personal server URL is required for server operations. \" +\n \"Please configure defaultPersonalServerUrl in your VanaConfig.\",\n );\n }\n return this.context.defaultPersonalServerUrl;\n }\n\n /**\n * Retrieves the cryptographic identity of a personal server.\n *\n * @remarks\n * This method fetches the public key and metadata for a personal server,\n * which is required for encrypting data before sharing with the server.\n * The identity includes the server's public key, address, and operational\n * details needed for secure communication. This information is cached\n * by identity servers to enable offline key retrieval.\n *\n * @param request - Parameters containing the user address\n * @param request.userAddress - The wallet address associated with the personal server\n * @returns Promise resolving to the server's identity information\n * @throws {NetworkError} When the identity service is unavailable or returns invalid data\n * @throws {PersonalServerError} When server identity cannot be retrieved\n * @example\n * ```typescript\n * // Get server identity for data encryption\n * const identity = await vana.server.getIdentity({\n * userAddress: \"0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36\"\n * });\n *\n * console.log(`Server: ${identity.name}`);\n * console.log(`Address: ${identity.address}`);\n * console.log(`Public Key: ${identity.publicKey}`);\n *\n * // Use the public key for encrypting data to share with this server\n * const encryptedData = await encryptWithWalletPublicKey(\n * userData,\n * identity.publicKey\n * );\n * ```\n */\n async getIdentity(\n request: InitPersonalServerParams,\n ): Promise<PersonalServerIdentity> {\n try {\n const response = await fetch(\n `${this.personalServerBaseUrl}/identity?address=${request.userAddress}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n );\n\n console.debug(\"🔍 Debug - getIdentity response\", response);\n if (!response.ok) {\n const errorText = await response.text();\n throw new NetworkError(\n `Local identity API request failed: ${response.status} ${response.statusText} - ${errorText}`,\n );\n }\n\n const serverResponse = (await response.json()) as IdentityResponseModel;\n\n return {\n kind: serverResponse.personal_server.kind,\n address: serverResponse.personal_server.address,\n publicKey: serverResponse.personal_server.public_key,\n baseUrl: this.personalServerBaseUrl,\n name: \"Hosted Vana Server\",\n };\n } catch (error) {\n if (\n error instanceof NetworkError ||\n error instanceof PersonalServerError\n ) {\n throw error;\n }\n throw new PersonalServerError(\n `Failed to get personal server identity: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Creates a server operation and returns its details as a plain object.\n *\n * @remarks\n * This method submits a computation request to the personal server and returns\n * an Operation object that can be serialized and passed across API boundaries.\n * Use `waitForOperation()` to poll for completion.\n *\n * @param params - The operation request parameters\n * @param params.permissionId - The permission ID authorizing this operation.\n * Obtain via `vana.permissions.getUserPermissionGrantsOnChain()`.\n * @returns An Operation object containing the operation ID and status\n * @throws {PersonalServerError} When the server request fails or parameters are invalid\n * @throws {NetworkError} When personal server API communication fails\n * @example\n * ```typescript\n * const operation = await vana.server.createOperation({\n * permissionId: 123\n * });\n * console.log(`Operation ID: ${operation.id}`);\n *\n * // Wait for completion\n * const result = await vana.server.waitForOperation(operation.id);\n * console.log(\"Result:\", result.result);\n * ```\n */\n async createOperation<T = unknown>(\n params: CreateOperationParams,\n ): Promise<Operation<T>> {\n this.assertWallet();\n\n try {\n const requestData = {\n permission_id: params.permissionId,\n };\n\n const requestJson = JSON.stringify(requestData);\n\n const signature = await this.createSignature(requestJson);\n\n const requestBody = {\n app_signature: signature,\n operation_request_json: requestJson,\n };\n\n // Step 5: Make request to personal server API\n console.debug(\"🔍 Debug - createOperation requestBody\", requestBody);\n const response = await this.makeRequest(requestBody);\n\n return {\n id: response.id,\n status: \"starting\",\n createdAt: Date.now(),\n } as Operation<T>;\n } catch (error) {\n if (error instanceof Error) {\n // Re-throw known Vana errors directly\n if (\n error instanceof NetworkError ||\n error instanceof SerializationError ||\n error instanceof SignatureError ||\n error instanceof PersonalServerError\n ) {\n throw error;\n }\n // Wrap unknown errors\n throw new PersonalServerError(\n `Personal server operation creation failed: ${error.message}`,\n error,\n );\n }\n throw new PersonalServerError(\n \"Personal server operation creation failed with unknown error\",\n );\n }\n }\n\n /**\n * Retrieves the current status and result of a server operation.\n *\n * @remarks\n * Common status values: `starting`, `running`, `succeeded`, `failed`, `canceled`.\n * When status is `succeeded`, the result field contains the operation output.\n *\n * @param operationId - The ID of the operation to query\n * @returns The operation as a plain object containing status, result, and metadata\n * @throws {NetworkError} When the API request fails or returns invalid data\n * @example\n * ```typescript\n * const operation = await vana.server.getOperation(operationId);\n * if (operation.status === 'succeeded') {\n * console.log('Result:', operation.result);\n * }\n * ```\n */\n async getOperation<T = unknown>(operationId: string): Promise<Operation<T>> {\n try {\n console.debug(\"Polling Operation Status:\", operationId);\n\n const response = await fetch(\n `${this.personalServerBaseUrl}/operations/${operationId}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n console.debug(\"Polling Error Response:\", {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n });\n throw new NetworkError(\n `Status polling failed: ${response.status} ${response.statusText} - ${errorText}`,\n );\n }\n\n const data = (await response.json()) as GetOperationResponse;\n\n console.debug(\"Polling Success Response:\", data);\n\n return {\n id: data.id,\n status: data.status as Operation[\"status\"],\n createdAt: Date.now(),\n updatedAt: Date.now(),\n result: data.status === \"succeeded\" ? (data.result as T) : undefined,\n error:\n data.status === \"failed\" ? (data.result ?? undefined) : undefined,\n };\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Failed to poll status: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Waits for an operation to complete and returns the final result.\n *\n * @remarks\n * This method polls the operation status at regular intervals until it\n * reaches a terminal state (succeeded, failed, or canceled). Supports\n * ergonomic overloads to accept either an Operation object or just the ID.\n *\n * @param opOrId - Either an Operation object or operation ID string\n * @param options - Optional polling configuration\n * @returns The completed operation with result or error\n * @throws {PersonalServerError} When the operation fails or times out\n * @example\n * ```typescript\n * // Using operation object\n * const operation = await vana.server.createOperation({ permissionId: 123 });\n * const completed = await vana.server.waitForOperation(operation);\n *\n * // Using just the ID\n * const completed = await vana.server.waitForOperation(\"op_abc123\");\n *\n * // With custom timeout\n * const completed = await vana.server.waitForOperation(operation, {\n * timeout: 60000,\n * pollingInterval: 1000\n * });\n * ```\n */\n async waitForOperation<T = unknown>(\n opOrId: Operation<T> | string,\n options?: PollingOptions,\n ): Promise<Operation<T>> {\n const id = typeof opOrId === \"string\" ? opOrId : opOrId.id;\n const startTime = Date.now();\n const timeout = options?.timeout ?? 30000;\n const interval = options?.pollingInterval ?? 500;\n\n while (true) {\n const operation = await this.getOperation<T>(id);\n\n if (operation.status === \"succeeded\") {\n return operation;\n }\n\n if (operation.status === \"failed\") {\n throw new PersonalServerError(\n `Operation ${operation.status}: ${operation.error ?? \"Unknown error\"}`,\n );\n }\n\n if (operation.status === \"canceled\") {\n throw new PersonalServerError(`Operation was canceled`);\n }\n\n if (Date.now() - startTime > timeout) {\n throw new PersonalServerError(`Operation timed out after ${timeout}ms`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n }\n\n /**\n * Cancels a running operation on the personal server.\n *\n * @remarks\n * This method attempts to cancel an operation that is currently processing\n * on the personal server. The operation must be in a cancellable state\n * (typically `starting` or `processing`). Not all operations support\n * cancellation, and cancellation may not be immediate. The server will\n * attempt to stop the operation and update its status to `canceled`.\n *\n * **Cancellation Behavior:**\n * - Operations in `succeeded` or `failed` states cannot be canceled\n * - Some long-running operations may take time to respond to cancellation\n * - Always verify cancellation by polling the operation status afterward\n *\n * @param operationId - The unique identifier of the operation to cancel,\n * obtained from `createOperation()` response\n * @returns Promise that resolves when the cancellation request is accepted\n * @throws {PersonalServerError} When the operation cannot be canceled or doesn't exist.\n * Check operation status - it may already be completed or failed.\n * @throws {NetworkError} When unable to reach the personal server API.\n * Verify server URL and network connectivity.\n * @example\n * ```typescript\n * // Start a long-running operation\n * const operation = await vana.server.createOperation({\n * permissionId: 123\n * });\n *\n * // Cancel if needed\n * try {\n * await vana.server.cancelOperation(operation.id);\n * console.log(\"Cancellation requested\");\n *\n * // Verify cancellation\n * const status = await vana.server.getOperation(operation.id);\n * if (status.status === \"canceled\") {\n * console.log(\"Operation successfully canceled\");\n * }\n * } catch (error) {\n * console.error(\"Failed to cancel:\", error);\n * }\n * ```\n */\n async cancelOperation(operationId: string): Promise<void> {\n try {\n const response = await fetch(\n `${this.personalServerBaseUrl}/operations/${operationId}/cancel`,\n {\n method: \"POST\",\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new PersonalServerError(\n `Failed to cancel operation: ${response.status} ${response.statusText} - ${errorText}`,\n );\n }\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Failed to cancel operation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Makes the request to the personal server API.\n *\n * @param requestBody - The post request parameters to serialize\n * @returns JSON string representation of the request data\n */\n private async makeRequest(\n requestBody: Record<string, unknown>,\n ): Promise<CreateOperationResponse> {\n try {\n console.debug(\"Personal Server Request:\", {\n url: `${this.personalServerBaseUrl}/operations`,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: requestBody,\n });\n\n const response = await fetch(`${this.personalServerBaseUrl}/operations`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.debug(\"Personal Server Error Response:\", {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n });\n throw new NetworkError(\n `Personal server API request failed: ${response.status} ${response.statusText} - ${errorText}`,\n );\n }\n\n const data = (await response.json()) as CreateOperationResponse;\n\n console.debug(\"Personal Server Success Response:\", data);\n\n return data;\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Failed to make personal server API request: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Creates a signature for the request JSON.\n *\n * @param requestJson - The JSON string to sign\n * @returns Promise resolving to the cryptographic signature\n */\n private async createSignature(requestJson: string): Promise<string> {\n try {\n console.debug(\"🔍 Debug - createSignature\", requestJson);\n\n // Use applicationClient if available, fallback to walletClient\n const client =\n this.context.applicationClient ?? this.context.walletClient;\n\n if (!client) {\n throw new SignatureError(\"No client available for signing\");\n }\n\n // Get the account from the wallet client\n const { account } = client;\n if (!account) {\n throw new SignatureError(\"No account available for signing\");\n }\n\n // Only allow local accounts for signing\n if (account.type !== \"local\") {\n throw new SignatureError(\n \"Only local accounts are supported for signing\",\n );\n }\n\n console.debug(\"🔍 Debug - createSignature account\", account);\n // Sign locally using the account's signMessage method\n const signature = await account.signMessage({\n message: requestJson,\n });\n\n return signature;\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"User rejected\")) {\n throw new SignatureError(\"User rejected the signature request\");\n }\n throw new SignatureError(\n `Failed to create signature: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/controllers/server.ts"],"sourcesContent":["import type {\n CreateOperationParams,\n InitPersonalServerParams,\n PersonalServerIdentity,\n} from \"../types\";\nimport type {\n CreateOperationResponse,\n GetOperationResponse,\n IdentityResponseModel,\n} from \"../generated/server/server-exports\";\nimport {\n NetworkError,\n SerializationError,\n SignatureError,\n PersonalServerError,\n} from \"../errors\";\nimport type { ControllerContext } from \"./permissions\";\nimport type { Operation, PollingOptions } from \"../types/operations\";\nimport { BaseController } from \"./base\";\n\n// Server types are now auto-imported from the generated exports\n\n/**\n * Manages personal server interactions for secure data processing.\n *\n * @remarks\n * Handles communication with personal servers for computation requests\n * and identity retrieval. Personal servers process user data with\n * cryptographic verification, ensuring privacy and permission compliance.\n *\n * **Architecture:**\n * Servers use deterministic key derivation from user addresses.\n * Identity cached for offline retrieval. Operations authenticated\n * via wallet signatures and permission verification.\n *\n * **Method Selection:**\n * - `getIdentity()` - Retrieve server public key for encryption\n * - `createOperation()` - Submit computation with permission ID\n * - `getOperation()` - Check status and retrieve results\n * - `waitForOperation()` - Poll until completion or timeout\n * - `cancelOperation()` - Stop running operations\n *\n * **Typical Workflow:**\n * 1. Get server identity for encryption key\n * 2. Create operation with permission ID\n * 3. Poll for completion\n * 4. Retrieve results\n *\n * @example\n * ```typescript\n * // Get server identity for encryption\n * const identity = await vana.server.getIdentity({\n * userAddress: \"0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36\"\n * });\n * console.log(`Server key: ${identity.publicKey}`);\n *\n * // Submit computation request\n * const operation = await vana.server.createOperation({\n * permissionId: 123\n * });\n *\n * // Wait for results\n * const result = await vana.server.waitForOperation(operation.id);\n * console.log(\"Processing complete:\", result.result);\n * ```\n *\n * @category Server Management\n * @see For conceptual overview, visit {@link https://docs.vana.org/docs/personal-servers}\n */\nexport class ServerController extends BaseController {\n constructor(context: ControllerContext) {\n super(context);\n }\n\n private get personalServerBaseUrl(): string {\n if (!this.context.defaultPersonalServerUrl) {\n throw new PersonalServerError(\n \"Personal server URL is required for server operations. \" +\n \"Please configure defaultPersonalServerUrl in your VanaConfig.\",\n );\n }\n return this.context.defaultPersonalServerUrl;\n }\n\n /**\n * Retrieves cryptographic identity for a personal server.\n *\n * @remarks\n * Fetches public key and metadata required for data encryption.\n * Identity cached by infrastructure for offline retrieval.\n * Each user address maps to deterministic server identity.\n *\n * @param request - Identity request parameters\n * @param request.userAddress - Wallet address of server owner\n *\n * @returns Server identity with public key and metadata\n *\n * @throws {NetworkError} Identity service unavailable.\n * Check network connection and server URL configuration.\n * @throws {PersonalServerError} Identity retrieval failed.\n * Verify user address and server registration.\n *\n * @example\n * ```typescript\n * const identity = await vana.server.getIdentity({\n * userAddress: \"0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36\"\n * });\n *\n * console.log(`Server: ${identity.name}`);\n * console.log(`Address: ${identity.address}`);\n * console.log(`Public Key: ${identity.publicKey}`);\n *\n * // Use for encryption before data sharing\n * const encrypted = await encryptWithPublicKey(\n * data,\n * identity.publicKey\n * );\n * ```\n */\n async getIdentity(\n request: InitPersonalServerParams,\n ): Promise<PersonalServerIdentity> {\n try {\n const response = await fetch(\n `${this.personalServerBaseUrl}/identity?address=${request.userAddress}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n );\n\n console.debug(\"🔍 Debug - getIdentity response\", response);\n if (!response.ok) {\n const errorText = await response.text();\n throw new NetworkError(\n `Local identity API request failed: ${response.status} ${response.statusText} - ${errorText}`,\n );\n }\n\n const serverResponse = (await response.json()) as IdentityResponseModel;\n\n return {\n kind: serverResponse.personal_server.kind,\n address: serverResponse.personal_server.address,\n publicKey: serverResponse.personal_server.public_key,\n baseUrl: this.personalServerBaseUrl,\n name: \"Hosted Vana Server\",\n };\n } catch (error) {\n if (\n error instanceof NetworkError ||\n error instanceof PersonalServerError\n ) {\n throw error;\n }\n throw new PersonalServerError(\n `Failed to get personal server identity: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Creates a server operation and returns its details as a plain object.\n *\n * @remarks\n * This method submits a computation request to the personal server and returns\n * an Operation object that can be serialized and passed across API boundaries.\n * Use `waitForOperation()` to poll for completion.\n *\n * @param params - The operation request parameters\n * @param params.permissionId - The permission ID authorizing this operation.\n * Obtain via `vana.permissions.getUserPermissionGrantsOnChain()`.\n * @returns An Operation object containing the operation ID and status\n * @throws {PersonalServerError} When the server request fails or parameters are invalid\n * @throws {NetworkError} When personal server API communication fails\n * @example\n * ```typescript\n * const operation = await vana.server.createOperation({\n * permissionId: 123\n * });\n * console.log(`Operation ID: ${operation.id}`);\n *\n * // Wait for completion\n * const result = await vana.server.waitForOperation(operation.id);\n * console.log(\"Result:\", result.result);\n * ```\n */\n async createOperation<T = unknown>(\n params: CreateOperationParams,\n ): Promise<Operation<T>> {\n this.assertWallet();\n\n try {\n const requestData = {\n permission_id: params.permissionId,\n };\n\n const requestJson = JSON.stringify(requestData);\n\n const signature = await this.createSignature(requestJson);\n\n const requestBody = {\n app_signature: signature,\n operation_request_json: requestJson,\n };\n\n // Step 5: Make request to personal server API\n console.debug(\"🔍 Debug - createOperation requestBody\", requestBody);\n const response = await this.makeRequest(requestBody);\n\n return {\n id: response.id,\n status: \"starting\",\n createdAt: Date.now(),\n } as Operation<T>;\n } catch (error) {\n if (error instanceof Error) {\n // Re-throw known Vana errors directly\n if (\n error instanceof NetworkError ||\n error instanceof SerializationError ||\n error instanceof SignatureError ||\n error instanceof PersonalServerError\n ) {\n throw error;\n }\n // Wrap unknown errors\n throw new PersonalServerError(\n `Personal server operation creation failed: ${error.message}`,\n error,\n );\n }\n throw new PersonalServerError(\n \"Personal server operation creation failed with unknown error\",\n );\n }\n }\n\n /**\n * Retrieves the current status and result of a server operation.\n *\n * @remarks\n * Common status values: `starting`, `running`, `succeeded`, `failed`, `canceled`.\n * When status is `succeeded`, the result field contains the operation output.\n *\n * @param operationId - The ID of the operation to query\n * @returns The operation as a plain object containing status, result, and metadata\n * @throws {NetworkError} When the API request fails or returns invalid data\n * @example\n * ```typescript\n * const operation = await vana.server.getOperation(operationId);\n * if (operation.status === 'succeeded') {\n * console.log('Result:', operation.result);\n * }\n * ```\n */\n async getOperation<T = unknown>(operationId: string): Promise<Operation<T>> {\n try {\n console.debug(\"Polling Operation Status:\", operationId);\n\n const response = await fetch(\n `${this.personalServerBaseUrl}/operations/${operationId}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n console.debug(\"Polling Error Response:\", {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n });\n throw new NetworkError(\n `Status polling failed: ${response.status} ${response.statusText} - ${errorText}`,\n );\n }\n\n const data = (await response.json()) as GetOperationResponse;\n\n console.debug(\"Polling Success Response:\", data);\n\n return {\n id: data.id,\n status: data.status as Operation[\"status\"],\n createdAt: Date.now(),\n updatedAt: Date.now(),\n result: data.status === \"succeeded\" ? (data.result as T) : undefined,\n error:\n data.status === \"failed\" ? (data.result ?? undefined) : undefined,\n };\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Failed to poll status: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Waits for an operation to complete and returns the final result.\n *\n * @remarks\n * This method polls the operation status at regular intervals until it\n * reaches a terminal state (succeeded, failed, or canceled). Supports\n * ergonomic overloads to accept either an Operation object or just the ID.\n *\n * @param opOrId - Either an Operation object or operation ID string\n * @param options - Optional polling configuration\n * @returns The completed operation with result or error\n * @throws {PersonalServerError} When the operation fails or times out\n * @example\n * ```typescript\n * // Using operation object\n * const operation = await vana.server.createOperation({ permissionId: 123 });\n * const completed = await vana.server.waitForOperation(operation);\n *\n * // Using just the ID\n * const completed = await vana.server.waitForOperation(\"op_abc123\");\n *\n * // With custom timeout\n * const completed = await vana.server.waitForOperation(operation, {\n * timeout: 60000,\n * pollingInterval: 1000\n * });\n * ```\n */\n async waitForOperation<T = unknown>(\n opOrId: Operation<T> | string,\n options?: PollingOptions,\n ): Promise<Operation<T>> {\n const id = typeof opOrId === \"string\" ? opOrId : opOrId.id;\n const startTime = Date.now();\n const timeout = options?.timeout ?? 30000;\n const interval = options?.pollingInterval ?? 500;\n\n while (true) {\n const operation = await this.getOperation<T>(id);\n\n if (operation.status === \"succeeded\") {\n return operation;\n }\n\n if (operation.status === \"failed\") {\n throw new PersonalServerError(\n `Operation ${operation.status}: ${operation.error ?? \"Unknown error\"}`,\n );\n }\n\n if (operation.status === \"canceled\") {\n throw new PersonalServerError(`Operation was canceled`);\n }\n\n if (Date.now() - startTime > timeout) {\n throw new PersonalServerError(`Operation timed out after ${timeout}ms`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n }\n\n /**\n * Cancels a running operation on the personal server.\n *\n * @remarks\n * This method attempts to cancel an operation that is currently processing\n * on the personal server. The operation must be in a cancellable state\n * (typically `starting` or `processing`). Not all operations support\n * cancellation, and cancellation may not be immediate. The server will\n * attempt to stop the operation and update its status to `canceled`.\n *\n * **Cancellation Behavior:**\n * - Operations in `succeeded` or `failed` states cannot be canceled\n * - Some long-running operations may take time to respond to cancellation\n * - Always verify cancellation by polling the operation status afterward\n *\n * @param operationId - The unique identifier of the operation to cancel,\n * obtained from `createOperation()` response\n * @returns Promise that resolves when the cancellation request is accepted\n * @throws {PersonalServerError} When the operation cannot be canceled or doesn't exist.\n * Check operation status - it may already be completed or failed.\n * @throws {NetworkError} When unable to reach the personal server API.\n * Verify server URL and network connectivity.\n * @example\n * ```typescript\n * // Start a long-running operation\n * const operation = await vana.server.createOperation({\n * permissionId: 123\n * });\n *\n * // Cancel if needed\n * try {\n * await vana.server.cancelOperation(operation.id);\n * console.log(\"Cancellation requested\");\n *\n * // Verify cancellation\n * const status = await vana.server.getOperation(operation.id);\n * if (status.status === \"canceled\") {\n * console.log(\"Operation successfully canceled\");\n * }\n * } catch (error) {\n * console.error(\"Failed to cancel:\", error);\n * }\n * ```\n */\n async cancelOperation(operationId: string): Promise<void> {\n try {\n const response = await fetch(\n `${this.personalServerBaseUrl}/operations/${operationId}/cancel`,\n {\n method: \"POST\",\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new PersonalServerError(\n `Failed to cancel operation: ${response.status} ${response.statusText} - ${errorText}`,\n );\n }\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Failed to cancel operation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Makes the request to the personal server API.\n *\n * @param requestBody - The post request parameters to serialize\n * @returns JSON string representation of the request data\n */\n private async makeRequest(\n requestBody: Record<string, unknown>,\n ): Promise<CreateOperationResponse> {\n try {\n console.debug(\"Personal Server Request:\", {\n url: `${this.personalServerBaseUrl}/operations`,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: requestBody,\n });\n\n const response = await fetch(`${this.personalServerBaseUrl}/operations`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.debug(\"Personal Server Error Response:\", {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n });\n throw new NetworkError(\n `Personal server API request failed: ${response.status} ${response.statusText} - ${errorText}`,\n );\n }\n\n const data = (await response.json()) as CreateOperationResponse;\n\n console.debug(\"Personal Server Success Response:\", data);\n\n return data;\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Failed to make personal server API request: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Creates a signature for the request JSON.\n *\n * @param requestJson - The JSON string to sign\n * @returns Promise resolving to the cryptographic signature\n */\n private async createSignature(requestJson: string): Promise<string> {\n try {\n console.debug(\"🔍 Debug - createSignature\", requestJson);\n\n // Use applicationClient if available, fallback to walletClient\n const client =\n this.context.applicationClient ?? this.context.walletClient;\n\n if (!client) {\n throw new SignatureError(\"No client available for signing\");\n }\n\n // Get the account from the wallet client\n const { account } = client;\n if (!account) {\n throw new SignatureError(\"No account available for signing\");\n }\n\n // Only allow local accounts for signing\n if (account.type !== \"local\") {\n throw new SignatureError(\n \"Only local accounts are supported for signing\",\n );\n }\n\n console.debug(\"🔍 Debug - createSignature account\", account);\n // Sign locally using the account's signMessage method\n const signature = await account.signMessage({\n message: requestJson,\n });\n\n return signature;\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"User rejected\")) {\n throw new SignatureError(\"User rejected the signature request\");\n }\n throw new SignatureError(\n `Failed to create signature: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -3,67 +3,75 @@ import type { ControllerContext } from "./permissions";
3
3
  import type { Operation, PollingOptions } from "../types/operations";
4
4
  import { BaseController } from "./base";
5
5
  /**
6
- * Manages interactions with Vana personal servers and identity infrastructure.
6
+ * Manages personal server interactions for secure data processing.
7
7
  *
8
8
  * @remarks
9
- * This controller handles communication with personal servers for data processing
10
- * and identity servers for public key derivation. It provides methods for posting
11
- * computation requests to personal servers, polling for results, and retrieving
12
- * cryptographic keys for secure data sharing. All server interactions use the
13
- * Replicate API infrastructure with proper authentication and error handling.
9
+ * Handles communication with personal servers for computation requests
10
+ * and identity retrieval. Personal servers process user data with
11
+ * cryptographic verification, ensuring privacy and permission compliance.
14
12
  *
15
- * **Server Identity System:**
16
- * Personal servers use deterministic key derivation: each user address maps to a specific server identity.
17
- * This enables secure communication without requiring servers to be online during key retrieval.
13
+ * **Architecture:**
14
+ * Servers use deterministic key derivation from user addresses.
15
+ * Identity cached for offline retrieval. Operations authenticated
16
+ * via wallet signatures and permission verification.
18
17
  *
19
18
  * **Method Selection:**
20
- * - `getIdentity()` retrieves server public keys and addresses for encryption setup
21
- * - `createOperation()` submits computation requests with signed permission verification
22
- * - `getOperation()` polls operation status and retrieves results when complete
23
- * - `cancelOperation()` stops running operations when cancellation is supported
19
+ * - `getIdentity()` - Retrieve server public key for encryption
20
+ * - `createOperation()` - Submit computation with permission ID
21
+ * - `getOperation()` - Check status and retrieve results
22
+ * - `waitForOperation()` - Poll until completion or timeout
23
+ * - `cancelOperation()` - Stop running operations
24
24
  *
25
- * **Workflow Pattern:**
26
- * Typical flow: Get identity Create operation → Poll status → Retrieve results
25
+ * **Typical Workflow:**
26
+ * 1. Get server identity for encryption key
27
+ * 2. Create operation with permission ID
28
+ * 3. Poll for completion
29
+ * 4. Retrieve results
27
30
  *
28
31
  * @example
29
32
  * ```typescript
30
- * // Get a server's identity including public key for encryption
33
+ * // Get server identity for encryption
31
34
  * const identity = await vana.server.getIdentity({
32
35
  * userAddress: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36"
33
36
  * });
37
+ * console.log(`Server key: ${identity.publicKey}`);
34
38
  *
35
- * // Create an operation using a granted permission
36
- * const response = await vana.server.createOperation({
37
- * permissionId: 123,
39
+ * // Submit computation request
40
+ * const operation = await vana.server.createOperation({
41
+ * permissionId: 123
38
42
  * });
39
43
  *
40
- * // Poll for computation results
41
- * const result = await vana.server.getOperation(response.id);
44
+ * // Wait for results
45
+ * const result = await vana.server.waitForOperation(operation.id);
46
+ * console.log("Processing complete:", result.result);
42
47
  * ```
48
+ *
43
49
  * @category Server Management
44
- * @see {@link https://docs.vana.com/developer/personal-servers | Vana Personal Servers} for conceptual overview
50
+ * @see For conceptual overview, visit {@link https://docs.vana.org/docs/personal-servers}
45
51
  */
46
52
  export declare class ServerController extends BaseController {
47
53
  constructor(context: ControllerContext);
48
54
  private get personalServerBaseUrl();
49
55
  /**
50
- * Retrieves the cryptographic identity of a personal server.
56
+ * Retrieves cryptographic identity for a personal server.
51
57
  *
52
58
  * @remarks
53
- * This method fetches the public key and metadata for a personal server,
54
- * which is required for encrypting data before sharing with the server.
55
- * The identity includes the server's public key, address, and operational
56
- * details needed for secure communication. This information is cached
57
- * by identity servers to enable offline key retrieval.
58
- *
59
- * @param request - Parameters containing the user address
60
- * @param request.userAddress - The wallet address associated with the personal server
61
- * @returns Promise resolving to the server's identity information
62
- * @throws {NetworkError} When the identity service is unavailable or returns invalid data
63
- * @throws {PersonalServerError} When server identity cannot be retrieved
59
+ * Fetches public key and metadata required for data encryption.
60
+ * Identity cached by infrastructure for offline retrieval.
61
+ * Each user address maps to deterministic server identity.
62
+ *
63
+ * @param request - Identity request parameters
64
+ * @param request.userAddress - Wallet address of server owner
65
+ *
66
+ * @returns Server identity with public key and metadata
67
+ *
68
+ * @throws {NetworkError} Identity service unavailable.
69
+ * Check network connection and server URL configuration.
70
+ * @throws {PersonalServerError} Identity retrieval failed.
71
+ * Verify user address and server registration.
72
+ *
64
73
  * @example
65
74
  * ```typescript
66
- * // Get server identity for data encryption
67
75
  * const identity = await vana.server.getIdentity({
68
76
  * userAddress: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36"
69
77
  * });
@@ -72,9 +80,9 @@ export declare class ServerController extends BaseController {
72
80
  * console.log(`Address: ${identity.address}`);
73
81
  * console.log(`Public Key: ${identity.publicKey}`);
74
82
  *
75
- * // Use the public key for encrypting data to share with this server
76
- * const encryptedData = await encryptWithWalletPublicKey(
77
- * userData,
83
+ * // Use for encryption before data sharing
84
+ * const encrypted = await encryptWithPublicKey(
85
+ * data,
78
86
  * identity.publicKey
79
87
  * );
80
88
  * ```
@@ -18,23 +18,25 @@ class ServerController extends BaseController {
18
18
  return this.context.defaultPersonalServerUrl;
19
19
  }
20
20
  /**
21
- * Retrieves the cryptographic identity of a personal server.
21
+ * Retrieves cryptographic identity for a personal server.
22
22
  *
23
23
  * @remarks
24
- * This method fetches the public key and metadata for a personal server,
25
- * which is required for encrypting data before sharing with the server.
26
- * The identity includes the server's public key, address, and operational
27
- * details needed for secure communication. This information is cached
28
- * by identity servers to enable offline key retrieval.
24
+ * Fetches public key and metadata required for data encryption.
25
+ * Identity cached by infrastructure for offline retrieval.
26
+ * Each user address maps to deterministic server identity.
27
+ *
28
+ * @param request - Identity request parameters
29
+ * @param request.userAddress - Wallet address of server owner
30
+ *
31
+ * @returns Server identity with public key and metadata
32
+ *
33
+ * @throws {NetworkError} Identity service unavailable.
34
+ * Check network connection and server URL configuration.
35
+ * @throws {PersonalServerError} Identity retrieval failed.
36
+ * Verify user address and server registration.
29
37
  *
30
- * @param request - Parameters containing the user address
31
- * @param request.userAddress - The wallet address associated with the personal server
32
- * @returns Promise resolving to the server's identity information
33
- * @throws {NetworkError} When the identity service is unavailable or returns invalid data
34
- * @throws {PersonalServerError} When server identity cannot be retrieved
35
38
  * @example
36
39
  * ```typescript
37
- * // Get server identity for data encryption
38
40
  * const identity = await vana.server.getIdentity({
39
41
  * userAddress: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36"
40
42
  * });
@@ -43,9 +45,9 @@ class ServerController extends BaseController {
43
45
  * console.log(`Address: ${identity.address}`);
44
46
  * console.log(`Public Key: ${identity.publicKey}`);
45
47
  *
46
- * // Use the public key for encrypting data to share with this server
47
- * const encryptedData = await encryptWithWalletPublicKey(
48
- * userData,
48
+ * // Use for encryption before data sharing
49
+ * const encrypted = await encryptWithPublicKey(
50
+ * data,
49
51
  * identity.publicKey
50
52
  * );
51
53
  * ```