Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@phala/cloud

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@phala/cloud - npm Package Compare versions

Comparing version
0.2.5
to
0.2.8
+164
dist/actions/apps/check_app_cvms_is_allowed.d.ts
import { z } from "zod";
export declare const AppCvmsBatchIsAllowedResponseSchema: z.ZodObject<{
is_onchain: z.ZodBoolean;
results: z.ZodDefault<z.ZodArray<z.ZodObject<{
app_contract_address: z.ZodString;
compose_hash: z.ZodString;
device_id: z.ZodString;
compose_hash_allowed: z.ZodBoolean;
allow_any_device: z.ZodBoolean;
device_id_allowed: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
is_allowed: z.ZodBoolean;
error: z.ZodOptional<z.ZodNullable<z.ZodString>>;
} & {
cvm_id: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
cvm_id: number;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
}, {
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
cvm_id: number;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
}>, "many">>;
total: z.ZodDefault<z.ZodNumber>;
allowed_count: z.ZodDefault<z.ZodNumber>;
denied_count: z.ZodDefault<z.ZodNumber>;
error_count: z.ZodDefault<z.ZodNumber>;
skipped_cvm_ids: z.ZodDefault<z.ZodArray<z.ZodNumber, "many">>;
}, "strip", z.ZodTypeAny, {
total: number;
is_onchain: boolean;
results: {
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
cvm_id: number;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
}[];
allowed_count: number;
denied_count: number;
error_count: number;
skipped_cvm_ids: number[];
}, {
is_onchain: boolean;
total?: number | undefined;
results?: {
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
cvm_id: number;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
}[] | undefined;
allowed_count?: number | undefined;
denied_count?: number | undefined;
error_count?: number | undefined;
skipped_cvm_ids?: number[] | undefined;
}>;
export type AppCvmsBatchIsAllowedResponse = z.infer<typeof AppCvmsBatchIsAllowedResponseSchema>;
export declare const CheckAppCvmsIsAllowedRequestSchema: z.ZodObject<{
appId: z.ZodString;
}, "strip", z.ZodTypeAny, {
appId: string;
}, {
appId: string;
}>;
export type CheckAppCvmsIsAllowedRequest = z.infer<typeof CheckAppCvmsIsAllowedRequestSchema>;
/**
* Batch check on-chain deployment allowance for all CVMs under an app.
*
* For on-chain KMS apps, queries the blockchain via multicall3 to check
* compose hash and device allowance for each CVM.
* For offchain KMS apps, returns is_onchain=false with no results.
*
* @param client - The API client
* @param request - Request parameters
* @param request.appId - The hex app identifier
* @returns Batch allowance check results for all CVMs
*/
declare const checkAppCvmsIsAllowed: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
appId: string;
}): Promise<{
total: number;
is_onchain: boolean;
results: {
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
cvm_id: number;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
}[];
allowed_count: number;
denied_count: number;
error_count: number;
skipped_cvm_ids: number[];
}>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
appId: string;
}, parameters: {
schema: T;
}): Promise<z.TypeOf<T>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
appId: string;
}, parameters: {
schema: false;
}): Promise<unknown>;
}, safeCheckAppCvmsIsAllowed: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
appId: string;
}): Promise<import("../..").SafeResult<{
total: number;
is_onchain: boolean;
results: {
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
cvm_id: number;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
}[];
allowed_count: number;
denied_count: number;
error_count: number;
skipped_cvm_ids: number[];
}>>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
appId: string;
}, parameters: {
schema: T;
}): Promise<import("../..").SafeResult<z.TypeOf<T>>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
appId: string;
}, parameters: {
schema: false;
}): Promise<import("../..").SafeResult<unknown>>;
};
export { checkAppCvmsIsAllowed, safeCheckAppCvmsIsAllowed };
import { z } from "zod";
export declare const CheckAppIsAllowedRequestSchema: z.ZodObject<{
appId: z.ZodString;
compose_hash: z.ZodString;
node_id: z.ZodOptional<z.ZodNumber>;
device_id: z.ZodOptional<z.ZodString>;
chain_id: z.ZodOptional<z.ZodNumber>;
}, "strip", z.ZodTypeAny, {
compose_hash: string;
appId: string;
chain_id?: number | undefined;
device_id?: string | undefined;
node_id?: number | undefined;
}, {
compose_hash: string;
appId: string;
chain_id?: number | undefined;
device_id?: string | undefined;
node_id?: number | undefined;
}>;
export type CheckAppIsAllowedRequest = z.infer<typeof CheckAppIsAllowedRequestSchema>;
/**
* Check if a deployment is allowed by an on-chain DStack App contract.
*
* Supports pure contract query (no DB) when all parameters including chain_id are provided.
*
* @param client - The API client
* @param request - Request parameters
* @param request.appId - App contract address
* @param request.compose_hash - Compose hash to check
* @param request.node_id - Node ID (resolves device_id from DB)
* @param request.device_id - Device ID (hex, direct)
* @param request.chain_id - Chain ID for RPC URL resolution
* @returns On-chain allowance check result
*/
declare const checkAppIsAllowed: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
compose_hash: string;
appId: string;
chain_id?: number | undefined;
device_id?: string | undefined;
node_id?: number | undefined;
}): Promise<{
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
cvm_id?: number | undefined;
}>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
compose_hash: string;
appId: string;
chain_id?: number | undefined;
device_id?: string | undefined;
node_id?: number | undefined;
}, parameters: {
schema: T;
}): Promise<z.TypeOf<T>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
compose_hash: string;
appId: string;
chain_id?: number | undefined;
device_id?: string | undefined;
node_id?: number | undefined;
}, parameters: {
schema: false;
}): Promise<unknown>;
}, safeCheckAppIsAllowed: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
compose_hash: string;
appId: string;
chain_id?: number | undefined;
device_id?: string | undefined;
node_id?: number | undefined;
}): Promise<import("../..").SafeResult<{
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
cvm_id?: number | undefined;
}>>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
compose_hash: string;
appId: string;
chain_id?: number | undefined;
device_id?: string | undefined;
node_id?: number | undefined;
}, parameters: {
schema: T;
}): Promise<import("../..").SafeResult<z.TypeOf<T>>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
compose_hash: string;
appId: string;
chain_id?: number | undefined;
device_id?: string | undefined;
node_id?: number | undefined;
}, parameters: {
schema: false;
}): Promise<import("../..").SafeResult<unknown>>;
};
export { checkAppIsAllowed, safeCheckAppIsAllowed };
import { type Chain, type Address, type PublicClient } from "viem";
/**
* Check whether a specific compose hash is allowed by a DstackApp contract.
*
* Reads the `allowedComposeHashes(hash)` mapping on-chain.
*
* @group Actions
* @since 0.7.0
*
* ## Usage
*
* ```typescript
* import { checkComposeHashAllowed } from '@phala/cloud'
* import { base } from 'viem/chains'
*
* const allowed = await checkComposeHashAllowed({
* chain: base,
* appAddress: "0x1234...abcd",
* composeHash: "0xaabbccdd...",
* })
* console.log(allowed) // true or false
* ```
*/
export type CheckComposeHashAllowedRequest = {
chain?: Chain;
rpcUrl?: string;
appAddress: Address;
composeHash: string;
publicClient?: PublicClient;
};
export declare function checkComposeHashAllowed(request: CheckComposeHashAllowedRequest): Promise<boolean>;
export declare function safeCheckComposeHashAllowed(request: CheckComposeHashAllowedRequest): Promise<{
success: true;
data: boolean;
} | {
success: false;
error: {
isRequestError: true;
message: string;
status: number;
detail: string;
};
}>;
import { type Chain, type Address, type PublicClient } from "viem";
/**
* Check on-chain prerequisites for a CVM update in a single RPC call.
*
* Uses `multicall` to batch-check:
* 1. `allowAnyDevice()` — whether the contract allows any device
* 2. `allowedDeviceIds(deviceId)` — whether the specific device is registered
* 3. `allowedComposeHashes(composeHash)` — whether the compose hash is already registered
*
* @group Actions
* @since 0.7.0
*
* ## Usage
*
* ```typescript
* import { checkOnChainPrerequisites } from '@phala/cloud'
* import { base } from 'viem/chains'
*
* const prereqs = await checkOnChainPrerequisites({
* chain: base,
* appAddress: "0x1234...abcd",
* deviceId: "0xaabbccdd...",
* composeHash: "0xeeff0011...",
* })
*
* if (!prereqs.deviceAllowed) {
* // Need to call addDevice first
* }
* if (prereqs.composeHashAllowed) {
* // Can skip addComposeHash transaction
* }
* ```
*/
export type CheckOnChainPrerequisitesRequest = {
chain?: Chain;
rpcUrl?: string;
appAddress: Address;
deviceId: string;
composeHash: string;
publicClient?: PublicClient;
};
export type OnChainPrerequisites = {
allowAnyDevice: boolean;
deviceAllowed: boolean;
composeHashAllowed: boolean;
};
export declare function checkOnChainPrerequisites(request: CheckOnChainPrerequisitesRequest): Promise<OnChainPrerequisites>;
export declare function safeCheckOnChainPrerequisites(request: CheckOnChainPrerequisitesRequest): Promise<{
success: true;
data: OnChainPrerequisites;
} | {
success: false;
error: {
isRequestError: true;
message: string;
status: number;
detail: string;
};
}>;
import { z } from "zod";
export declare const IsAllowedResultSchema: z.ZodObject<{
cvm_id: z.ZodOptional<z.ZodNumber>;
app_contract_address: z.ZodString;
compose_hash: z.ZodString;
device_id: z.ZodString;
compose_hash_allowed: z.ZodBoolean;
allow_any_device: z.ZodBoolean;
device_id_allowed: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
is_allowed: z.ZodBoolean;
error: z.ZodOptional<z.ZodNullable<z.ZodString>>;
}, "strip", z.ZodTypeAny, {
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
cvm_id?: number | undefined;
}, {
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
cvm_id?: number | undefined;
}>;
export type IsAllowedResult = z.infer<typeof IsAllowedResultSchema>;
declare const CheckCvmIsAllowedInputSchema: z.ZodObject<{
cvmId: z.ZodString;
compose_hash: z.ZodOptional<z.ZodString>;
node_id: z.ZodOptional<z.ZodNumber>;
device_id: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
cvmId: string;
device_id?: string | undefined;
compose_hash?: string | undefined;
node_id?: number | undefined;
}, {
cvmId: string;
device_id?: string | undefined;
compose_hash?: string | undefined;
node_id?: number | undefined;
}>;
export declare const CheckCvmIsAllowedRequestSchema: z.ZodObject<{
cvmId: z.ZodString;
compose_hash: z.ZodOptional<z.ZodString>;
node_id: z.ZodOptional<z.ZodNumber>;
device_id: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
cvmId: string;
device_id?: string | undefined;
compose_hash?: string | undefined;
node_id?: number | undefined;
}, {
cvmId: string;
device_id?: string | undefined;
compose_hash?: string | undefined;
node_id?: number | undefined;
}>;
export type CheckCvmIsAllowedRequest = z.infer<typeof CheckCvmIsAllowedInputSchema>;
/**
* Check if a CVM deployment is allowed by its on-chain DStack App contract.
*
* @param client - The API client
* @param request - Request parameters
* @param request.cvmId - CVM identifier
* @param request.compose_hash - Optional compose hash override
* @param request.node_id - Optional node ID override (resolves device_id)
* @param request.device_id - Optional device ID override
* @returns On-chain allowance check result
*/
declare const checkCvmIsAllowed: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
cvmId: string;
device_id?: string | undefined;
compose_hash?: string | undefined;
node_id?: number | undefined;
}): Promise<{
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
cvm_id?: number | undefined;
}>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
cvmId: string;
device_id?: string | undefined;
compose_hash?: string | undefined;
node_id?: number | undefined;
}, parameters: {
schema: T;
}): Promise<z.TypeOf<T>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
cvmId: string;
device_id?: string | undefined;
compose_hash?: string | undefined;
node_id?: number | undefined;
}, parameters: {
schema: false;
}): Promise<unknown>;
}, safeCheckCvmIsAllowed: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
cvmId: string;
device_id?: string | undefined;
compose_hash?: string | undefined;
node_id?: number | undefined;
}): Promise<import("../..").SafeResult<{
device_id: string;
compose_hash: string;
compose_hash_allowed: boolean;
is_allowed: boolean;
app_contract_address: string;
allow_any_device: boolean;
error?: string | null | undefined;
device_id_allowed?: boolean | null | undefined;
cvm_id?: number | undefined;
}>>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
cvmId: string;
device_id?: string | undefined;
compose_hash?: string | undefined;
node_id?: number | undefined;
}, parameters: {
schema: T;
}): Promise<import("../..").SafeResult<z.TypeOf<T>>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params: {
cvmId: string;
device_id?: string | undefined;
compose_hash?: string | undefined;
node_id?: number | undefined;
}, parameters: {
schema: false;
}): Promise<import("../..").SafeResult<unknown>>;
};
export { checkCvmIsAllowed, safeCheckCvmIsAllowed };
import { z } from "zod";
/**
* Commit CVM update (token-based, no auth required)
*
* Completes a two-phase CVM update using a one-time commit token generated
* during a prepare-only PATCH request. This enables multisig workflows where
* the on-chain signer is different from the original API caller.
*
* @example
* ```typescript
* import { createClient, patchCvm, commitCvmUpdate } from '@phala/cloud'
*
* const client = createClient()
*
* // Phase 1: prepare-only
* const result = await patchCvm(client, {
* id: 'my-cvm',
* docker_compose_file: newComposeYaml,
* prepareOnly: true,
* })
*
* if (result.requiresOnChainHash && result.commitToken) {
* // ... multisig approval happens externally ...
*
* // Phase 2: commit with token
* const committed = await commitCvmUpdate(client, {
* id: 'my-cvm',
* token: result.commitToken,
* composeHash: result.composeHash,
* transactionHash: '0x...',
* })
* console.log(`Update started: ${committed.correlationId}`)
* }
* ```
*/
export declare const CommitCvmUpdateRequestSchema: z.ZodEffects<z.ZodObject<{
id: z.ZodOptional<z.ZodString>;
uuid: z.ZodOptional<z.ZodString>;
app_id: z.ZodOptional<z.ZodString>;
instance_id: z.ZodOptional<z.ZodString>;
name: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
} & {
token: z.ZodString;
composeHash: z.ZodString;
transactionHash: z.ZodString;
}, "strip", z.ZodTypeAny, {
composeHash: string;
transactionHash: string;
token: string;
name?: string | undefined;
id?: string | undefined;
app_id?: string | undefined;
instance_id?: string | undefined;
uuid?: string | undefined;
}, {
composeHash: string;
transactionHash: string;
token: string;
name?: string | undefined;
id?: string | undefined;
app_id?: string | undefined;
instance_id?: string | undefined;
uuid?: string | undefined;
}>, any, any>;
export type CommitCvmUpdateRequest = z.input<typeof CommitCvmUpdateRequestSchema>;
declare const CommitCvmUpdateResultSchema: z.ZodObject<{
correlationId: z.ZodString;
status: z.ZodString;
}, "strip", z.ZodTypeAny, {
status: string;
correlationId: string;
}, {
status: string;
correlationId: string;
}>;
export type CommitCvmUpdateResult = z.infer<typeof CommitCvmUpdateResultSchema>;
declare const commitCvmUpdate: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any): Promise<{
status: string;
correlationId: string;
}>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: T;
} | undefined): Promise<z.TypeOf<T>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: false;
} | undefined): Promise<unknown>;
}, safeCommitCvmUpdate: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any): Promise<import("../..").SafeResult<{
status: string;
correlationId: string;
}>>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: T;
} | undefined): Promise<import("../..").SafeResult<z.TypeOf<T>>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: false;
} | undefined): Promise<import("../..").SafeResult<unknown>>;
};
export { commitCvmUpdate, safeCommitCvmUpdate };
import { z } from "zod";
/**
* Confirm CVM patch (Phase 2 of on-chain KMS update)
*
* Completes a two-phase CVM update by providing the compose hash and transaction
* hash proving on-chain registration. Call this after `patchCvm` returns
* `{ requiresOnChainHash: true }` and you have registered the compose hash on-chain.
*
* @example
* ```typescript
* import { createClient, patchCvm, confirmCvmPatch, addComposeHash } from '@phala/cloud'
*
* const client = createClient()
*
* const result = await patchCvm(client, {
* id: 'my-cvm',
* docker_compose_file: newComposeYaml,
* })
*
* if (result.requiresOnChainHash) {
* const tx = await addComposeHash(client, {
* composeHash: result.composeHash,
* kmsContractAddress: result.kmsInfo.kms_contract_address,
* // ... wallet config
* })
*
* const confirmed = await confirmCvmPatch(client, {
* id: 'my-cvm',
* composeHash: result.composeHash,
* transactionHash: tx.transactionHash,
* })
* console.log(`Update started: ${confirmed.correlationId}`)
* }
* ```
*/
export declare const ConfirmCvmPatchRequestSchema: z.ZodEffects<z.ZodObject<{
id: z.ZodOptional<z.ZodString>;
uuid: z.ZodOptional<z.ZodString>;
app_id: z.ZodOptional<z.ZodString>;
instance_id: z.ZodOptional<z.ZodString>;
name: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
} & {
composeHash: z.ZodString;
transactionHash: z.ZodString;
}, "strip", z.ZodTypeAny, {
composeHash: string;
transactionHash: string;
name?: string | undefined;
id?: string | undefined;
app_id?: string | undefined;
instance_id?: string | undefined;
uuid?: string | undefined;
}, {
composeHash: string;
transactionHash: string;
name?: string | undefined;
id?: string | undefined;
app_id?: string | undefined;
instance_id?: string | undefined;
uuid?: string | undefined;
}>, any, any>;
export type ConfirmCvmPatchRequest = z.input<typeof ConfirmCvmPatchRequestSchema>;
declare const ConfirmCvmPatchResultSchema: z.ZodObject<{
correlationId: z.ZodString;
}, "strip", z.ZodTypeAny, {
correlationId: string;
}, {
correlationId: string;
}>;
export type ConfirmCvmPatchResult = z.infer<typeof ConfirmCvmPatchResultSchema>;
declare const confirmCvmPatch: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any): Promise<{
correlationId: string;
}>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: T;
} | undefined): Promise<z.TypeOf<T>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: false;
} | undefined): Promise<unknown>;
}, safeConfirmCvmPatch: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any): Promise<import("../..").SafeResult<{
correlationId: string;
}>>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: T;
} | undefined): Promise<import("../..").SafeResult<z.TypeOf<T>>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: false;
} | undefined): Promise<import("../..").SafeResult<unknown>>;
};
export { confirmCvmPatch, safeConfirmCvmPatch };
import { z } from "zod";
/**
* Patch CVM (unified update)
*
* Applies partial updates to a CVM via the unified PATCH endpoint. Only fields
* present in the request are applied (true PATCH semantics).
*
* For contract-owned KMS (ETHEREUM/BASE), compose-hash-affecting changes trigger
* a two-phase flow: the first call returns `{ requiresOnChainHash: true, ... }`
* with the compose hash to register on-chain. After registration, call
* `confirmCvmPatch` with the compose hash and transaction hash.
*
* @example
* ```typescript
* import { createClient, patchCvm, confirmCvmPatch, addComposeHash } from '@phala/cloud'
*
* const client = createClient()
*
* // Simple update (non-on-chain KMS or non-compose-hash-affecting fields)
* const result = await patchCvm(client, {
* id: 'my-cvm',
* vcpu: 4,
* memory: 8192,
* })
* // result.requiresOnChainHash === false
* console.log(result.correlationId)
*
* // On-chain KMS compose update (two-phase)
* const result = await patchCvm(client, {
* id: 'my-cvm',
* docker_compose_file: newComposeYaml,
* })
*
* if (result.requiresOnChainHash) {
* const tx = await addComposeHash(client, {
* composeHash: result.composeHash,
* kmsContractAddress: result.kmsInfo.kms_contract_address,
* // ... wallet config
* })
* await confirmCvmPatch(client, {
* id: 'my-cvm',
* composeHash: result.composeHash,
* transactionHash: tx.transactionHash,
* })
* }
* ```
*/
export declare const PatchCvmRequestSchema: z.ZodEffects<z.ZodObject<{
id: z.ZodOptional<z.ZodString>;
uuid: z.ZodOptional<z.ZodString>;
app_id: z.ZodOptional<z.ZodString>;
instance_id: z.ZodOptional<z.ZodString>;
name: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
} & {
docker_compose_file: z.ZodOptional<z.ZodString>;
pre_launch_script: z.ZodOptional<z.ZodString>;
allowed_envs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
public_logs: z.ZodOptional<z.ZodBoolean>;
public_sysinfo: z.ZodOptional<z.ZodBoolean>;
public_tcbinfo: z.ZodOptional<z.ZodBoolean>;
encrypted_env: z.ZodOptional<z.ZodString>;
user_config: z.ZodOptional<z.ZodString>;
gpus: z.ZodOptional<z.ZodObject<{
count: z.ZodNumber;
product_name: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
count: number;
product_name?: string | undefined;
}, {
count: number;
product_name?: string | undefined;
}>>;
vcpu: z.ZodOptional<z.ZodNumber>;
memory: z.ZodOptional<z.ZodNumber>;
disk_size: z.ZodOptional<z.ZodNumber>;
image: z.ZodOptional<z.ZodString>;
shutdown_timeout: z.ZodOptional<z.ZodNumber>;
allow_force_stop: z.ZodOptional<z.ZodBoolean>;
prepareOnly: z.ZodOptional<z.ZodBoolean>;
}, "strip", z.ZodTypeAny, {
name?: string | undefined;
image?: string | undefined;
id?: string | undefined;
app_id?: string | undefined;
instance_id?: string | undefined;
vcpu?: number | undefined;
memory?: number | undefined;
disk_size?: number | undefined;
public_sysinfo?: boolean | undefined;
public_logs?: boolean | undefined;
gpus?: {
count: number;
product_name?: string | undefined;
} | undefined;
public_tcbinfo?: boolean | undefined;
uuid?: string | undefined;
allowed_envs?: string[] | undefined;
docker_compose_file?: string | undefined;
pre_launch_script?: string | undefined;
encrypted_env?: string | undefined;
user_config?: string | undefined;
shutdown_timeout?: number | undefined;
allow_force_stop?: boolean | undefined;
prepareOnly?: boolean | undefined;
}, {
name?: string | undefined;
image?: string | undefined;
id?: string | undefined;
app_id?: string | undefined;
instance_id?: string | undefined;
vcpu?: number | undefined;
memory?: number | undefined;
disk_size?: number | undefined;
public_sysinfo?: boolean | undefined;
public_logs?: boolean | undefined;
gpus?: {
count: number;
product_name?: string | undefined;
} | undefined;
public_tcbinfo?: boolean | undefined;
uuid?: string | undefined;
allowed_envs?: string[] | undefined;
docker_compose_file?: string | undefined;
pre_launch_script?: string | undefined;
encrypted_env?: string | undefined;
user_config?: string | undefined;
shutdown_timeout?: number | undefined;
allow_force_stop?: boolean | undefined;
prepareOnly?: boolean | undefined;
}>, any, any>;
export type PatchCvmRequest = z.input<typeof PatchCvmRequestSchema>;
declare const PatchCvmAcceptedSchema: z.ZodObject<{
requiresOnChainHash: z.ZodLiteral<false>;
correlationId: z.ZodString;
}, "strip", z.ZodTypeAny, {
requiresOnChainHash: false;
correlationId: string;
}, {
requiresOnChainHash: false;
correlationId: string;
}>;
declare const PatchCvmHashRequiredSchema: z.ZodObject<{
requiresOnChainHash: z.ZodLiteral<true>;
composeHash: z.ZodString;
appId: z.ZodString;
deviceId: z.ZodString;
kmsInfo: z.ZodEffects<z.ZodObject<{
id: z.ZodString;
slug: z.ZodNullable<z.ZodString>;
url: z.ZodString;
version: z.ZodString;
chain_id: z.ZodNullable<z.ZodNumber>;
kms_contract_address: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
gateway_app_id: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
id: z.ZodString;
slug: z.ZodNullable<z.ZodString>;
url: z.ZodString;
version: z.ZodString;
chain_id: z.ZodNullable<z.ZodNumber>;
kms_contract_address: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
gateway_app_id: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
id: z.ZodString;
slug: z.ZodNullable<z.ZodString>;
url: z.ZodString;
version: z.ZodString;
chain_id: z.ZodNullable<z.ZodNumber>;
kms_contract_address: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
gateway_app_id: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
}, z.ZodTypeAny, "passthrough">>, z.objectOutputType<{
id: z.ZodString;
slug: z.ZodNullable<z.ZodString>;
url: z.ZodString;
version: z.ZodString;
chain_id: z.ZodNullable<z.ZodNumber>;
kms_contract_address: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
gateway_app_id: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
id: z.ZodString;
slug: z.ZodNullable<z.ZodString>;
url: z.ZodString;
version: z.ZodString;
chain_id: z.ZodNullable<z.ZodNumber>;
kms_contract_address: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
gateway_app_id: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
}, z.ZodTypeAny, "passthrough">>;
commitToken: z.ZodOptional<z.ZodString>;
commitUrl: z.ZodOptional<z.ZodString>;
apiCommitUrl: z.ZodOptional<z.ZodString>;
onchainStatus: z.ZodOptional<z.ZodObject<{
compose_hash_allowed: z.ZodBoolean;
device_id_allowed: z.ZodBoolean;
is_allowed: z.ZodBoolean;
}, "strip", z.ZodTypeAny, {
compose_hash_allowed: boolean;
device_id_allowed: boolean;
is_allowed: boolean;
}, {
compose_hash_allowed: boolean;
device_id_allowed: boolean;
is_allowed: boolean;
}>>;
}, "strip", z.ZodTypeAny, {
deviceId: string;
composeHash: string;
appId: string;
requiresOnChainHash: true;
kmsInfo: {
version: string;
id: string;
slug: string | null;
url: string;
chain_id: number | null;
kms_contract_address: `0x${string}`;
gateway_app_id: `0x${string}`;
} & {
[k: string]: unknown;
};
commitToken?: string | undefined;
commitUrl?: string | undefined;
apiCommitUrl?: string | undefined;
onchainStatus?: {
compose_hash_allowed: boolean;
device_id_allowed: boolean;
is_allowed: boolean;
} | undefined;
}, {
deviceId: string;
composeHash: string;
appId: string;
requiresOnChainHash: true;
kmsInfo: {
version: string;
id: string;
slug: string | null;
url: string;
chain_id: number | null;
kms_contract_address: string | null;
gateway_app_id: string | null;
} & {
[k: string]: unknown;
};
commitToken?: string | undefined;
commitUrl?: string | undefined;
apiCommitUrl?: string | undefined;
onchainStatus?: {
compose_hash_allowed: boolean;
device_id_allowed: boolean;
is_allowed: boolean;
} | undefined;
}>;
export declare const PatchCvmResultSchema: z.ZodDiscriminatedUnion<"requiresOnChainHash", [z.ZodObject<{
requiresOnChainHash: z.ZodLiteral<false>;
correlationId: z.ZodString;
}, "strip", z.ZodTypeAny, {
requiresOnChainHash: false;
correlationId: string;
}, {
requiresOnChainHash: false;
correlationId: string;
}>, z.ZodObject<{
requiresOnChainHash: z.ZodLiteral<true>;
composeHash: z.ZodString;
appId: z.ZodString;
deviceId: z.ZodString;
kmsInfo: z.ZodEffects<z.ZodObject<{
id: z.ZodString;
slug: z.ZodNullable<z.ZodString>;
url: z.ZodString;
version: z.ZodString;
chain_id: z.ZodNullable<z.ZodNumber>;
kms_contract_address: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
gateway_app_id: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
id: z.ZodString;
slug: z.ZodNullable<z.ZodString>;
url: z.ZodString;
version: z.ZodString;
chain_id: z.ZodNullable<z.ZodNumber>;
kms_contract_address: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
gateway_app_id: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
id: z.ZodString;
slug: z.ZodNullable<z.ZodString>;
url: z.ZodString;
version: z.ZodString;
chain_id: z.ZodNullable<z.ZodNumber>;
kms_contract_address: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
gateway_app_id: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
}, z.ZodTypeAny, "passthrough">>, z.objectOutputType<{
id: z.ZodString;
slug: z.ZodNullable<z.ZodString>;
url: z.ZodString;
version: z.ZodString;
chain_id: z.ZodNullable<z.ZodNumber>;
kms_contract_address: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
gateway_app_id: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
id: z.ZodString;
slug: z.ZodNullable<z.ZodString>;
url: z.ZodString;
version: z.ZodString;
chain_id: z.ZodNullable<z.ZodNumber>;
kms_contract_address: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
gateway_app_id: z.ZodEffects<z.ZodNullable<z.ZodString>, `0x${string}`, string | null>;
}, z.ZodTypeAny, "passthrough">>;
commitToken: z.ZodOptional<z.ZodString>;
commitUrl: z.ZodOptional<z.ZodString>;
apiCommitUrl: z.ZodOptional<z.ZodString>;
onchainStatus: z.ZodOptional<z.ZodObject<{
compose_hash_allowed: z.ZodBoolean;
device_id_allowed: z.ZodBoolean;
is_allowed: z.ZodBoolean;
}, "strip", z.ZodTypeAny, {
compose_hash_allowed: boolean;
device_id_allowed: boolean;
is_allowed: boolean;
}, {
compose_hash_allowed: boolean;
device_id_allowed: boolean;
is_allowed: boolean;
}>>;
}, "strip", z.ZodTypeAny, {
deviceId: string;
composeHash: string;
appId: string;
requiresOnChainHash: true;
kmsInfo: {
version: string;
id: string;
slug: string | null;
url: string;
chain_id: number | null;
kms_contract_address: `0x${string}`;
gateway_app_id: `0x${string}`;
} & {
[k: string]: unknown;
};
commitToken?: string | undefined;
commitUrl?: string | undefined;
apiCommitUrl?: string | undefined;
onchainStatus?: {
compose_hash_allowed: boolean;
device_id_allowed: boolean;
is_allowed: boolean;
} | undefined;
}, {
deviceId: string;
composeHash: string;
appId: string;
requiresOnChainHash: true;
kmsInfo: {
version: string;
id: string;
slug: string | null;
url: string;
chain_id: number | null;
kms_contract_address: string | null;
gateway_app_id: string | null;
} & {
[k: string]: unknown;
};
commitToken?: string | undefined;
commitUrl?: string | undefined;
apiCommitUrl?: string | undefined;
onchainStatus?: {
compose_hash_allowed: boolean;
device_id_allowed: boolean;
is_allowed: boolean;
} | undefined;
}>]>;
export type PatchCvmResult = z.infer<typeof PatchCvmResultSchema>;
export type PatchCvmAccepted = z.infer<typeof PatchCvmAcceptedSchema>;
export type PatchCvmHashRequired = z.infer<typeof PatchCvmHashRequiredSchema>;
declare const patchCvm: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any): Promise<{
requiresOnChainHash: false;
correlationId: string;
} | {
deviceId: string;
composeHash: string;
appId: string;
requiresOnChainHash: true;
kmsInfo: {
version: string;
id: string;
slug: string | null;
url: string;
chain_id: number | null;
kms_contract_address: `0x${string}`;
gateway_app_id: `0x${string}`;
} & {
[k: string]: unknown;
};
commitToken?: string | undefined;
commitUrl?: string | undefined;
apiCommitUrl?: string | undefined;
onchainStatus?: {
compose_hash_allowed: boolean;
device_id_allowed: boolean;
is_allowed: boolean;
} | undefined;
}>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: T;
} | undefined): Promise<z.TypeOf<T>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: false;
} | undefined): Promise<unknown>;
}, safePatchCvm: {
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any): Promise<import("../..").SafeResult<{
requiresOnChainHash: false;
correlationId: string;
} | {
deviceId: string;
composeHash: string;
appId: string;
requiresOnChainHash: true;
kmsInfo: {
version: string;
id: string;
slug: string | null;
url: string;
chain_id: number | null;
kms_contract_address: `0x${string}`;
gateway_app_id: `0x${string}`;
} & {
[k: string]: unknown;
};
commitToken?: string | undefined;
commitUrl?: string | undefined;
apiCommitUrl?: string | undefined;
onchainStatus?: {
compose_hash_allowed: boolean;
device_id_allowed: boolean;
is_allowed: boolean;
} | undefined;
}>>;
<T extends z.ZodTypeAny>(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: T;
} | undefined): Promise<import("../..").SafeResult<z.TypeOf<T>>>;
(client: import("../..").BaseClient<import("../..").ApiVersion>, params?: any, parameters?: {
schema: false;
} | undefined): Promise<import("../..").SafeResult<unknown>>;
};
export { patchCvm, safePatchCvm };
/**
* Phala Cloud API structured error codes.
*
* Use with ResourceError.errorCode to match specific errors:
* ```typescript
* if (error instanceof ResourceError && error.errorCode === ErrorCodes.CVM_APP_ID_CONFLICT) {
* // handle idempotency conflict
* }
* ```
*/
export declare const ErrorCodes: {
readonly NODE_NOT_FOUND: "ERR-01-001";
readonly COMPOSE_FILE_REQUIRED: "ERR-01-002";
readonly INVALID_COMPOSE_FILE: "ERR-01-003";
readonly DUPLICATE_CVM_NAME: "ERR-01-004";
readonly HASH_REGISTRATION_REQUIRED: "ERR-01-005";
readonly HASH_INVALID_OR_EXPIRED: "ERR-01-006";
readonly TX_VERIFICATION_FAILED: "ERR-01-007";
readonly HASH_NOT_ALLOWED: "ERR-01-008";
readonly INSTANCE_TYPE_NOT_FOUND: "ERR-02-001";
readonly RESOURCE_NOT_AVAILABLE: "ERR-02-002";
readonly INSUFFICIENT_VCPU: "ERR-02-003";
readonly INSUFFICIENT_MEMORY: "ERR-02-004";
readonly INSUFFICIENT_SLOTS: "ERR-02-005";
readonly GPU_ALLOCATION_ERROR: "ERR-02-006";
readonly INSUFFICIENT_GPU: "ERR-02-007";
readonly INVALID_REQUEST: "ERR-02-008";
readonly INCOMPATIBLE_CONFIG: "ERR-02-009";
readonly IMAGE_NOT_FOUND: "ERR-02-010";
readonly KMS_NOT_FOUND: "ERR-02-011";
readonly TEEPOD_NOT_ACCESSIBLE: "ERR-02-012";
readonly OS_IMAGE_NOT_COMPATIBLE: "ERR-02-013";
readonly NODE_CAPACITY_NOT_CONFIGURED: "ERR-02-014";
readonly QUOTA_EXCEEDED: "ERR-02-015";
readonly CVM_NOT_FOUND: "ERR-03-001";
readonly MULTIPLE_CVMS_SAME_NAME: "ERR-03-002";
readonly CVM_NOT_IN_WORKSPACE: "ERR-03-003";
readonly CVM_ACCESS_DENIED: "ERR-03-005";
readonly REPLICA_IMAGE_NOT_AVAILABLE: "ERR-03-006";
readonly CVM_APP_ID_CONFLICT: "ERR-03-007";
readonly INSUFFICIENT_BALANCE: "ERR-04-001";
readonly MAX_CVM_LIMIT: "ERR-04-002";
readonly RESOURCE_LIMIT_EXCEEDED: "ERR-04-003";
readonly TOKEN_LIMIT_EXCEEDED: "ERR-05-001";
readonly TOKEN_RATE_LIMIT: "ERR-05-002";
readonly OAUTH_EMAIL_INVALID: "ERR-06-001";
};
export type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
/** Webhook event envelope */
export interface WebhookEvent<T = unknown> {
id: string;
event: string;
version: string;
created_at: string;
workspace: {
id: string;
name: string;
};
data: T;
}
/**
* Verify an HMAC-SHA256 webhook signature.
*
* @returns true if signature is valid and timestamp is within tolerance
*/
export declare function verifyWebhookSignature(params: {
secret: string;
timestamp: string;
body: string;
signature: string;
toleranceSeconds?: number;
}): boolean;
/**
* Parse and verify a webhook event from HTTP request headers and body.
*
* @throws Error if signature is invalid, timestamp is expired, or headers are missing
*/
export declare function parseWebhookEvent<T = unknown>(params: {
headers: Record<string, string | string[] | undefined>;
body: string;
secret: string;
toleranceSeconds?: number;
}): WebhookEvent<T>;
/**
* Webhook signature verification utilities.
*
* Exported separately from the main entry point because these
* depend on `node:crypto` and must not be included in browser bundles.
*
* Usage:
* import { verifyWebhookSignature, parseWebhookEvent } from "@phala/cloud/webhook";
*/
export { verifyWebhookSignature, parseWebhookEvent } from "./utils/verify-webhook";
export type { WebhookEvent } from "./utils/verify-webhook";
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/webhook.ts
var webhook_exports = {};
__export(webhook_exports, {
parseWebhookEvent: () => parseWebhookEvent,
verifyWebhookSignature: () => verifyWebhookSignature
});
module.exports = __toCommonJS(webhook_exports);
// src/utils/verify-webhook.ts
var import_node_crypto = require("crypto");
function verifyWebhookSignature(params) {
const { secret, timestamp, body, signature, toleranceSeconds = 300 } = params;
const ts = Number.parseInt(timestamp, 10);
if (Number.isNaN(ts)) return false;
const now = Math.floor(Date.now() / 1e3);
if (Math.abs(now - ts) > toleranceSeconds) return false;
const expected = `sha256=${(0, import_node_crypto.createHmac)("sha256", secret).update(`${timestamp}.${body}`).digest("hex")}`;
const expectedBuf = Buffer.from(expected, "utf-8");
const actualBuf = Buffer.from(signature, "utf-8");
if (expectedBuf.length !== actualBuf.length) return false;
return (0, import_node_crypto.timingSafeEqual)(expectedBuf, actualBuf);
}
function parseWebhookEvent(params) {
const { headers, body, secret, toleranceSeconds } = params;
const normalised = {};
for (const [key, value] of Object.entries(headers)) {
const resolved = Array.isArray(value) ? value[0] : value;
if (resolved != null) {
normalised[key.toLowerCase()] = resolved;
}
}
const timestamp = normalised["x-webhook-timestamp"];
const signature = normalised["x-webhook-signature"];
if (!timestamp || !signature) {
throw new Error(
"Missing required webhook headers: X-Webhook-Timestamp and X-Webhook-Signature"
);
}
const valid = verifyWebhookSignature({ secret, timestamp, body, signature, toleranceSeconds });
if (!valid) {
throw new Error("Invalid webhook signature or expired timestamp");
}
return JSON.parse(body);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
parseWebhookEvent,
verifyWebhookSignature
});
// src/utils/verify-webhook.ts
import { createHmac, timingSafeEqual } from "crypto";
function verifyWebhookSignature(params) {
const { secret, timestamp, body, signature, toleranceSeconds = 300 } = params;
const ts = Number.parseInt(timestamp, 10);
if (Number.isNaN(ts)) return false;
const now = Math.floor(Date.now() / 1e3);
if (Math.abs(now - ts) > toleranceSeconds) return false;
const expected = `sha256=${createHmac("sha256", secret).update(`${timestamp}.${body}`).digest("hex")}`;
const expectedBuf = Buffer.from(expected, "utf-8");
const actualBuf = Buffer.from(signature, "utf-8");
if (expectedBuf.length !== actualBuf.length) return false;
return timingSafeEqual(expectedBuf, actualBuf);
}
function parseWebhookEvent(params) {
const { headers, body, secret, toleranceSeconds } = params;
const normalised = {};
for (const [key, value] of Object.entries(headers)) {
const resolved = Array.isArray(value) ? value[0] : value;
if (resolved != null) {
normalised[key.toLowerCase()] = resolved;
}
}
const timestamp = normalised["x-webhook-timestamp"];
const signature = normalised["x-webhook-signature"];
if (!timestamp || !signature) {
throw new Error(
"Missing required webhook headers: X-Webhook-Timestamp and X-Webhook-Signature"
);
}
const valid = verifyWebhookSignature({ secret, timestamp, body, signature, toleranceSeconds });
if (!valid) {
throw new Error("Invalid webhook signature or expired timestamp");
}
return JSON.parse(body);
}
export {
parseWebhookEvent,
verifyWebhookSignature
};
+2
-2

@@ -57,4 +57,4 @@ import { z } from "zod";

chain_id?: number | null | undefined;
app_contract_address?: string | null | undefined;
allow_any_device?: boolean | null | undefined;
app_contract_address?: string | null | undefined;
}, {

@@ -70,4 +70,4 @@ is_onchain_kms: boolean;

}[] | undefined;
app_contract_address?: string | null | undefined;
allow_any_device?: boolean | null | undefined;
app_contract_address?: string | null | undefined;
}>;

@@ -74,0 +74,0 @@ export type DeviceAllowlistItem = z.infer<typeof DeviceAllowlistItemSchema>;

@@ -72,2 +72,32 @@ /**

}, {
readonly inputs: readonly [{
readonly internalType: "bytes32";
readonly name: "";
readonly type: "bytes32";
}];
readonly name: "allowedComposeHashes";
readonly outputs: readonly [{
readonly internalType: "bool";
readonly name: "";
readonly type: "bool";
}];
readonly stateMutability: "view";
readonly type: "function";
}, {
readonly inputs: readonly [{
readonly internalType: "address";
readonly name: "owner";
readonly type: "address";
}];
readonly name: "OwnableInvalidOwner";
readonly type: "error";
}, {
readonly inputs: readonly [{
readonly internalType: "address";
readonly name: "account";
readonly type: "address";
}];
readonly name: "OwnableUnauthorizedAccount";
readonly type: "error";
}, {
readonly anonymous: false;

@@ -74,0 +104,0 @@ readonly inputs: readonly [{

@@ -87,2 +87,21 @@ import { z } from "zod";

*
* ## Idempotency
*
* This endpoint is idempotent: submitting the same `app_id` + `compose_hash`
* again returns the existing CVM (safe retry after network timeout). A different
* `compose_hash` for the same `app_id` throws a `ResourceError` with error code
* `ERR-03-007` (`CVM_APP_ID_CONFLICT`, HTTP 409).
*
* ```typescript
* import { isAppIdConflictError } from '@phala/cloud'
*
* try {
* const cvm = await commitCvmProvision(client, payload)
* } catch (error) {
* if (isAppIdConflictError(error)) {
* // app_id already used with a different compose_hash
* }
* }
* ```
*
* ## Schema Parameter

@@ -89,0 +108,0 @@ *

@@ -360,2 +360,3 @@ import { z } from "zod";

}, z.ZodTypeAny, "passthrough">>>>;
compose_hash_registered: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{

@@ -406,2 +407,3 @@ app_id: z.ZodNullable<z.ZodString>;

}, z.ZodTypeAny, "passthrough">>>>;
compose_hash_registered: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{

@@ -452,2 +454,3 @@ app_id: z.ZodNullable<z.ZodString>;

}, z.ZodTypeAny, "passthrough">>>>;
compose_hash_registered: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
}, z.ZodTypeAny, "passthrough">>;

@@ -499,2 +502,3 @@ export declare const ProvisionCvmComposeFileUpdateSchema: z.ZodObject<{

}, z.ZodTypeAny, "passthrough">>>>;
compose_hash_registered: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{

@@ -545,2 +549,3 @@ app_id: z.ZodNullable<z.ZodString>;

}, z.ZodTypeAny, "passthrough">>>>;
compose_hash_registered: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{

@@ -591,2 +596,3 @@ app_id: z.ZodNullable<z.ZodString>;

}, z.ZodTypeAny, "passthrough">>>>;
compose_hash_registered: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
}, z.ZodTypeAny, "passthrough">>;

@@ -672,2 +678,3 @@ export type ProvisionCvmComposeFileUpdateRequest = z.input<typeof ProvisionCvmComposeFileUpdateRequestSchema>;

}, z.ZodTypeAny, "passthrough">>>>;
compose_hash_registered: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
}, z.ZodTypeAny, "passthrough">>;

@@ -795,2 +802,3 @@ <T extends z.ZodTypeAny>(client: Client<import("../..").ApiVersion>, params: {

}, z.ZodTypeAny, "passthrough">>>>;
compose_hash_registered: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
}, z.ZodTypeAny, "passthrough">>>;

@@ -797,0 +805,0 @@ <T extends z.ZodTypeAny>(client: Client<import("../..").ApiVersion>, params: {

@@ -12,2 +12,4 @@ export { getCurrentUser, safeGetCurrentUser, CurrentUserSchema, type CurrentUser, } from "./get_current_user";

export { checkDeviceAllowed, safeCheckDeviceAllowed, type CheckDeviceAllowedRequest, } from "./blockchains/check_device_allowed";
export { checkComposeHashAllowed, safeCheckComposeHashAllowed, type CheckComposeHashAllowedRequest, } from "./blockchains/check_compose_hash_allowed";
export { checkOnChainPrerequisites, safeCheckOnChainPrerequisites, type CheckOnChainPrerequisitesRequest, type OnChainPrerequisites, } from "./blockchains/check_on_chain_prerequisites";
export { dstackAppAbi } from "./blockchains/abi/dstack_app";

@@ -43,2 +45,5 @@ export { getCvmComposeFile, safeGetCvmComposeFile, type GetCvmComposeFileResult, GetCvmComposeFileRequestSchema, type GetCvmComposeFileRequest, } from "./cvms/get_cvm_compose_file";

export { getCvmDockerCompose, safeGetCvmDockerCompose, GetCvmDockerComposeRequestSchema, type GetCvmDockerComposeRequest, } from "./cvms/get_cvm_docker_compose";
export { patchCvm, safePatchCvm, PatchCvmRequestSchema, PatchCvmResultSchema, type PatchCvmRequest, type PatchCvmResult, type PatchCvmAccepted, type PatchCvmHashRequired, } from "./cvms/patch_cvm";
export { confirmCvmPatch, safeConfirmCvmPatch, ConfirmCvmPatchRequestSchema, type ConfirmCvmPatchRequest, type ConfirmCvmPatchResult, } from "./cvms/confirm_cvm_patch";
export { commitCvmUpdate, safeCommitCvmUpdate, CommitCvmUpdateRequestSchema, type CommitCvmUpdateRequest, type CommitCvmUpdateResult, } from "./cvms/commit_cvm_update";
export { updateCvmResources, safeUpdateCvmResources, UpdateCvmResourcesRequestSchema, type UpdateCvmResourcesRequest, } from "./cvms/update_cvm_resources";

@@ -60,2 +65,5 @@ export { updateCvmVisibility, safeUpdateCvmVisibility, UpdateCvmVisibilityRequestSchema, type UpdateCvmVisibilityRequest, } from "./cvms/update_cvm_visibility";

export { syncGithubSshKeys, safeSyncGithubSshKeys, SyncGithubSshKeysResponseSchema, type SyncGithubSshKeysResponse, } from "./ssh_keys/sync_github_ssh_keys";
export { checkCvmIsAllowed, safeCheckCvmIsAllowed, IsAllowedResultSchema, CheckCvmIsAllowedRequestSchema, type IsAllowedResult, type CheckCvmIsAllowedRequest, } from "./cvms/check_cvm_is_allowed";
export { checkAppIsAllowed, safeCheckAppIsAllowed, CheckAppIsAllowedRequestSchema, type CheckAppIsAllowedRequest, } from "./apps/check_app_is_allowed";
export { checkAppCvmsIsAllowed, safeCheckAppCvmsIsAllowed, AppCvmsBatchIsAllowedResponseSchema, CheckAppCvmsIsAllowedRequestSchema, type AppCvmsBatchIsAllowedResponse, type CheckAppCvmsIsAllowedRequest, } from "./apps/check_app_cvms_is_allowed";
export { getAppList, safeGetAppList, GetAppListRequestSchema, type GetAppListRequest, } from "./apps/get_app_list";

@@ -62,0 +70,0 @@ export { getAppInfo, safeGetAppInfo, GetAppInfoRequestSchema, type GetAppInfoRequest, } from "./apps/get_app_info";

@@ -91,2 +91,7 @@ import { ofetch, type FetchOptions, type FetchRequest } from "ofetch";

/**
* Build request options, stripping Content-Type when body is FormData
* so the browser/runtime sets the correct multipart boundary automatically.
*/
private buildRequestOptions;
/**
* Perform POST request (throws PhalaCloudError on error)

@@ -93,0 +98,0 @@ */

@@ -86,3 +86,3 @@ import { z } from "zod";

export type CvmOsInfoV20260121 = z.infer<typeof CvmOsInfoV20260121Schema>;
export declare const CvmKmsInfoV20260121Schema: z.ZodObject<{
export declare const CvmKmsInfoV20260121Schema: z.ZodEffects<z.ZodObject<{
chain_id: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;

@@ -108,2 +108,16 @@ dstack_kms_address: z.ZodOptional<z.ZodNullable<z.ZodString>>;

rpc_endpoint?: string | null | undefined;
}>, {
chain_id?: number | null | undefined;
encrypted_env_pubkey?: string | null | undefined;
deployer_address?: string | null | undefined;
dstack_kms_address?: string | null | undefined;
dstack_app_address?: string | null | undefined;
rpc_endpoint?: string | null | undefined;
}, {
chain_id?: number | null | undefined;
encrypted_env_pubkey?: string | null | undefined;
deployer_address?: string | null | undefined;
dstack_kms_address?: string | null | undefined;
dstack_app_address?: string | null | undefined;
rpc_endpoint?: string | null | undefined;
}>;

@@ -270,3 +284,3 @@ export type CvmKmsInfoV20260121 = z.infer<typeof CvmKmsInfoV20260121Schema>;

kms_type: z.ZodOptional<z.ZodNullable<z.ZodEnum<["phala", "ethereum", "base", "legacy"]>>>;
kms_info: z.ZodOptional<z.ZodNullable<z.ZodObject<{
kms_info: z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodObject<{
chain_id: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;

@@ -292,2 +306,16 @@ dstack_kms_address: z.ZodOptional<z.ZodNullable<z.ZodString>>;

rpc_endpoint?: string | null | undefined;
}>, {
chain_id?: number | null | undefined;
encrypted_env_pubkey?: string | null | undefined;
deployer_address?: string | null | undefined;
dstack_kms_address?: string | null | undefined;
dstack_app_address?: string | null | undefined;
rpc_endpoint?: string | null | undefined;
}, {
chain_id?: number | null | undefined;
encrypted_env_pubkey?: string | null | undefined;
deployer_address?: string | null | undefined;
dstack_kms_address?: string | null | undefined;
dstack_app_address?: string | null | undefined;
rpc_endpoint?: string | null | undefined;
}>>>;

@@ -602,3 +630,3 @@ status: z.ZodString;

kms_type: z.ZodOptional<z.ZodNullable<z.ZodEnum<["phala", "ethereum", "base", "legacy"]>>>;
kms_info: z.ZodOptional<z.ZodNullable<z.ZodObject<{
kms_info: z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodObject<{
chain_id: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;

@@ -624,2 +652,16 @@ dstack_kms_address: z.ZodOptional<z.ZodNullable<z.ZodString>>;

rpc_endpoint?: string | null | undefined;
}>, {
chain_id?: number | null | undefined;
encrypted_env_pubkey?: string | null | undefined;
deployer_address?: string | null | undefined;
dstack_kms_address?: string | null | undefined;
dstack_app_address?: string | null | undefined;
rpc_endpoint?: string | null | undefined;
}, {
chain_id?: number | null | undefined;
encrypted_env_pubkey?: string | null | undefined;
deployer_address?: string | null | undefined;
dstack_kms_address?: string | null | undefined;
dstack_app_address?: string | null | undefined;
rpc_endpoint?: string | null | undefined;
}>>>;

@@ -939,3 +981,3 @@ status: z.ZodString;

kms_type: z.ZodOptional<z.ZodNullable<z.ZodEnum<["phala", "ethereum", "base", "legacy"]>>>;
kms_info: z.ZodOptional<z.ZodNullable<z.ZodObject<{
kms_info: z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodObject<{
chain_id: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;

@@ -961,2 +1003,16 @@ dstack_kms_address: z.ZodOptional<z.ZodNullable<z.ZodString>>;

rpc_endpoint?: string | null | undefined;
}>, {
chain_id?: number | null | undefined;
encrypted_env_pubkey?: string | null | undefined;
deployer_address?: string | null | undefined;
dstack_kms_address?: string | null | undefined;
dstack_app_address?: string | null | undefined;
rpc_endpoint?: string | null | undefined;
}, {
chain_id?: number | null | undefined;
encrypted_env_pubkey?: string | null | undefined;
deployer_address?: string | null | undefined;
dstack_kms_address?: string | null | undefined;
dstack_app_address?: string | null | undefined;
rpc_endpoint?: string | null | undefined;
}>>>;

@@ -963,0 +1019,0 @@ status: z.ZodString;

@@ -379,1 +379,10 @@ import { z } from "zod";

}): string;
/**
* Check if an error is a conflict error (409).
*/
export declare function isConflictError(error: PhalaCloudError): boolean;
/**
* Check if an error is an app_id conflict from idempotent CVM creation.
* This means the app_id already has an active CVM with a different compose_hash.
*/
export declare function isAppIdConflictError(error: PhalaCloudError): error is ResourceError;

@@ -6,5 +6,6 @@ export { encryptEnvVars } from "@phala/dstack-sdk/encrypt-env-vars";

export { isValidHostname, convertToHostname, generateFallbackHostname, generateDefaultCvmName, } from "./hostname";
export { parseApiError, PhalaCloudError, RequestError, ValidationError, AuthError, BusinessError, ServerError, UnknownError, ResourceError, formatValidationErrors, formatErrorMessage, formatStructuredError, getErrorMessage, getValidationFields, type ValidationErrorItem, type StructuredErrorDetail, type ErrorLink, type StructuredErrorResponse, ApiErrorSchema, type ApiError, } from "./errors";
export { parseApiError, PhalaCloudError, RequestError, ValidationError, AuthError, BusinessError, ServerError, UnknownError, ResourceError, formatValidationErrors, formatErrorMessage, formatStructuredError, getErrorMessage, isConflictError, isAppIdConflictError, getValidationFields, type ValidationErrorItem, type StructuredErrorDetail, type ErrorLink, type StructuredErrorResponse, ApiErrorSchema, type ApiError, } from "./errors";
export { ErrorCodes, type ErrorCode } from "./error_codes";
export { createNetworkClients, extractNetworkClients, checkNetworkStatus, checkBalance, validateNetworkPrerequisites, waitForTransactionReceipt, executeTransaction, NetworkError, WalletError, TransactionError, type NetworkConfig, type WalletConnection, type NetworkClients, type BalanceCheckResult, type TransactionOptions, type TransactionResult, } from "./network";
export { createTransactionTracker, executeBatchTransactions, executeTransactionWithRetry, estimateTransactionGas, type TransactionState, type TransactionStatus, type TransactionTracker, type BatchTransactionOptions, type BatchTransactionResult, type RetryOptions, type GasEstimationOptions, } from "./transaction";
export { createClientsFromPrivateKey, createClientsFromBrowser, autoCreateClients, switchToNetwork, addNetwork, } from "./client-factories";
{
"name": "@phala/cloud",
"version": "0.2.5",
"version": "0.2.8",
"description": "TypeScript SDK for Phala Cloud API",

@@ -14,2 +14,7 @@ "main": "dist/index.js",

},
"./webhook": {
"types": "./dist/webhook.d.ts",
"import": "./dist/webhook.mjs",
"require": "./dist/webhook.js"
},
"./package.json": "./package.json"

@@ -19,3 +24,3 @@ },

"scripts": {
"build": "tsup src/index.ts --format cjs,esm && tsc --emitDeclarationOnly --declaration --outDir dist",
"build": "tsup src/index.ts src/webhook.ts --format cjs,esm && tsc --emitDeclarationOnly --declaration --outDir dist",
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",

@@ -22,0 +27,0 @@ "fmt": "biome format --write",

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display