@opendatalabs/vana-sdk 3.22.0-pr.207.e47cd30 → 3.22.0-pr.208.dac9856

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/direct/escrow-payment.ts"],"sourcesContent":["/**\n * Escrow-backed payment authorization for the Direct Data Controller.\n *\n * @remarks\n * Builds on the DPv2 escrow surface added in `protocol/escrow`. When a Personal\n * Server read returns `402 Payment Required`, the controller settles the\n * challenged operation through the escrow gateway:\n *\n * 1. Sign the challenge's `GenericPayment` EIP-712 message with the app key.\n * 2. POST it to the gateway's `/v1/escrow/pay` via {@link EscrowGatewayClient}.\n * 3. Map the gateway's {@link EscrowPayResult} into a typed\n * {@link DirectPaymentReceipt} for the caller to inspect.\n *\n * This module supports legacy `\"grant\"` operations and receipt-bound\n * `\"data_access\"` operations. It adapts the escrow `payForOp` flow to the\n * direct-read use case; it does not define its own payment scheme.\n *\n * @category Direct\n * @module direct/escrow-payment\n */\n\nimport {\n GENERIC_PAYMENT_TYPES,\n NATIVE_ASSET_ADDRESS,\n genericPaymentDomain,\n type EscrowAccessRecord,\n type EscrowGatewayClient,\n type EscrowPayResult,\n type PaymentBreakdown,\n} from \"../protocol/escrow\";\nimport type {\n DirectFeeBreakdown,\n DirectPaymentReceipt,\n DirectPaymentResponseMetadata,\n PersonalServerPaymentOperation,\n PersonalServerPaymentRequired,\n} from \"./types\";\n\n/** The escrow `GenericPayment.opType` used for grant-lifecycle payments. */\nexport const GRANT_OP_TYPE = \"grant\" as const;\n/** The escrow `GenericPayment.opType` used for receipt-bound data access. */\nexport const DATA_ACCESS_OP_TYPE = \"data_access\" as const;\n\n/**\n * EIP-712 typed-data signer (e.g. viem `account.signTypedData`).\n *\n * @remarks\n * Kept structurally minimal so any viem account/wallet client satisfies it\n * without the SDK depending on viem's exact `signTypedData` overload set.\n */\nexport type SignTypedDataFn = (args: {\n domain: ReturnType<typeof genericPaymentDomain>;\n types: typeof GENERIC_PAYMENT_TYPES;\n primaryType: \"GenericPayment\";\n message: {\n payerAddress: `0x${string}`;\n opType: string;\n opId: `0x${string}`;\n asset: `0x${string}`;\n amount: bigint;\n paymentNonce: bigint;\n };\n}) => Promise<`0x${string}`>;\n\n/** Supplies a monotonically-increasing payment nonce per payer. */\nexport type PaymentNonceSource = (\n payerAddress: string,\n) => Promise<bigint> | bigint;\n\ninterface EscrowPaymentMessage {\n payerAddress: `0x${string}`;\n opType: typeof GRANT_OP_TYPE | typeof DATA_ACCESS_OP_TYPE;\n opId: `0x${string}`;\n asset: `0x${string}`;\n amount: string;\n paymentNonce: string;\n}\n\ninterface SignedEscrowPayment {\n message: EscrowPaymentMessage;\n signature: `0x${string}`;\n accessRecord?: EscrowAccessRecord;\n}\n\ninterface X402PaymentHeader {\n x402Version: 1;\n scheme: \"vana-escrow-grant\";\n network: string;\n payload: SignedEscrowPayment;\n}\n\n/** Configuration required to sign an escrow X-PAYMENT header. */\nexport interface EscrowPaymentHeaderConfig {\n /** Deployed `DataPortabilityEscrow` contract address. */\n escrowContract: `0x${string}`;\n /** Chain id for the EIP-712 domain (1480 mainnet, 14800 moksha). */\n chainId: number;\n /** App EIP-712 signer. */\n signTypedData: SignTypedDataFn;\n /**\n * Supplies the next payment nonce for a payer. Defaults to a process-local\n * monotonic counter seeded at 1. Provide a durable source in production so\n * nonces survive restarts (the gateway rejects reused (payer, nonce) pairs).\n */\n nonceSource?: PaymentNonceSource;\n}\n\n/**\n * Escrow settlement configuration for gateway authorization.\n *\n * @remarks\n * Extends the header-signing boundary with the gateway client used by\n * {@link authorizeEscrowPayment}. Existing controller and legacy wrapper\n * callers can continue to provide this full configuration.\n */\nexport interface EscrowPaymentConfig extends EscrowPaymentHeaderConfig {\n /** Client for the gateway escrow endpoints (`/v1/escrow/*`). */\n client: EscrowGatewayClient;\n}\n\n/** Map the gateway {@link PaymentBreakdown} into the public {@link DirectFeeBreakdown}. */\nexport function toDirectFeeBreakdown(\n breakdown: PaymentBreakdown,\n): DirectFeeBreakdown {\n return {\n registrationFee: breakdown.registrationFee,\n dataAccessFee: breakdown.dataAccessFee,\n registrationPaid: breakdown.registrationPaid,\n };\n}\n\n/** Map a gateway {@link EscrowPayResult} into the public {@link DirectPaymentReceipt}. */\nexport function toDirectPaymentReceipt(\n result: EscrowPayResult,\n): DirectPaymentReceipt {\n return {\n opType: result.opType,\n opId: result.opId,\n asset: result.asset,\n amount: result.amount,\n paymentNonce: result.paymentNonce,\n breakdown: toDirectFeeBreakdown(result.breakdown),\n paidAt: result.paidAt,\n };\n}\n\n/** Default in-process monotonic nonce counter (seeded at 1 per payer). */\nexport function createDefaultNonceSource(): PaymentNonceSource {\n const counters = new Map<string, bigint>();\n return (payerAddress: string): bigint => {\n const key = payerAddress.toLowerCase();\n const next = (counters.get(key) ?? 0n) + 1n;\n counters.set(key, next);\n return next;\n };\n}\n\nconst processLocalNonceSource = createDefaultNonceSource();\nconst UINT256_MAX = (1n << 256n) - 1n;\nconst ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\nconst BYTES32_RE = /^0x[0-9a-fA-F]{64}$/;\nconst SIGNATURE_RE = /^0x[0-9a-fA-F]{130}$/;\n\nfunction isUint256Decimal(value: string, allowZero: boolean): boolean {\n const pattern = allowZero ? /^(0|[1-9]\\d*)$/ : /^[1-9]\\d*$/;\n return (\n value.length <= UINT256_MAX.toString().length &&\n pattern.test(value) &&\n BigInt(value) <= UINT256_MAX\n );\n}\n\nfunction isValidAccessRecord(record: EscrowAccessRecord): boolean {\n return (\n BYTES32_RE.test(record.dataPointId) &&\n isUint256Decimal(record.version, false) &&\n ADDRESS_RE.test(record.accessor) &&\n BYTES32_RE.test(record.recordId) &&\n SIGNATURE_RE.test(record.signature)\n );\n}\n\nfunction validateSigningOperation(\n payerAddress: `0x${string}`,\n required: PersonalServerPaymentOperation,\n): void {\n if (!ADDRESS_RE.test(payerAddress)) {\n throw new Error(\"Payment payer must be a 20-byte EVM address\");\n }\n if (!BYTES32_RE.test(required.opId)) {\n throw new Error(\"Payment operation id must be a 32-byte hex value\");\n }\n if (!ADDRESS_RE.test(required.asset || NATIVE_ASSET_ADDRESS)) {\n throw new Error(\"Payment asset must be a 20-byte EVM address\");\n }\n if (!isUint256Decimal(required.amount, true)) {\n throw new Error(\"Payment amount must be a canonical uint256 decimal\");\n }\n if (\n required.paymentNonce !== undefined &&\n !isUint256Decimal(required.paymentNonce, false)\n ) {\n throw new Error(\"Payment nonce must be a positive uint256 decimal\");\n }\n\n const accessRecord = required.accessRecord;\n if (required.opType === DATA_ACCESS_OP_TYPE) {\n if (!accessRecord || !isValidAccessRecord(accessRecord)) {\n throw new Error(\"Data-access payment requires a valid access record\");\n }\n if (required.opId.toLowerCase() !== accessRecord.recordId.toLowerCase()) {\n throw new Error(\n \"Data-access payment operation id must equal the access record id\",\n );\n }\n if (accessRecord.accessor.toLowerCase() !== payerAddress.toLowerCase()) {\n throw new Error(\n \"Data-access payment accessor must equal the payment payer address\",\n );\n }\n return;\n }\n\n if (required.amount === \"0\") {\n if (\n !accessRecord ||\n !isValidAccessRecord(accessRecord) ||\n accessRecord.accessor.toLowerCase() !== payerAddress.toLowerCase()\n ) {\n throw new Error(\n \"Zero-amount grant payments require a valid access record for the payer\",\n );\n }\n }\n}\n\nfunction base64EncodeJson(value: unknown): string {\n const bytes = new TextEncoder().encode(JSON.stringify(value));\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n\nfunction base64DecodeJson(value: string): unknown {\n const binary = atob(value);\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return JSON.parse(new TextDecoder().decode(bytes));\n}\n\nasync function signEscrowPayment(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentOperation;\n config: EscrowPaymentHeaderConfig;\n}): Promise<SignedEscrowPayment> {\n const { payerAddress, required, config } = params;\n validateSigningOperation(payerAddress, required);\n const nonceSource = config.nonceSource ?? processLocalNonceSource;\n const paymentNonce = BigInt(\n required.paymentNonce ?? (await nonceSource(payerAddress)),\n );\n const asset = (required.asset || NATIVE_ASSET_ADDRESS) as `0x${string}`;\n const opId = required.opId as `0x${string}`;\n const amount = BigInt(required.amount);\n if (amount < 0n || amount > UINT256_MAX) {\n throw new Error(\"Payment amount must be a uint256\");\n }\n if (paymentNonce <= 0n || paymentNonce > UINT256_MAX) {\n throw new Error(\"Payment nonce must be a positive uint256\");\n }\n\n const message = {\n payerAddress,\n opType: required.opType,\n opId,\n asset,\n amount,\n paymentNonce,\n };\n\n const signature = await config.signTypedData({\n domain: genericPaymentDomain(config.chainId, config.escrowContract),\n types: GENERIC_PAYMENT_TYPES,\n primaryType: \"GenericPayment\",\n message,\n });\n\n return {\n message: {\n ...message,\n amount: amount.toString(),\n paymentNonce: paymentNonce.toString(),\n },\n signature,\n ...(required.accessRecord ? { accessRecord: required.accessRecord } : {}),\n };\n}\n\n/**\n * Build the canonical X-PAYMENT header for a validated escrow operation.\n *\n * @remarks\n * Supports both legacy grant payments and receipt-bound data-access payments.\n * Signing is injected through {@link EscrowPaymentHeaderConfig.signTypedData}.\n */\nexport async function buildEscrowPaymentHeader(params: {\n /** Address whose escrow balance pays for the operation. */\n payerAddress: `0x${string}`;\n /** Validated operation parsed from the Personal Server challenge. */\n required: PersonalServerPaymentOperation;\n /** Escrow contract, chain, signer, and nonce configuration. */\n config: EscrowPaymentHeaderConfig;\n}): Promise<string> {\n const network = params.required.network ?? `vana:${params.config.chainId}`;\n if (network !== `vana:${params.config.chainId}`) {\n throw new Error(\"Payment network must match the configured chain\");\n }\n\n const signed = await signEscrowPayment(params);\n const payment: X402PaymentHeader = {\n x402Version: 1,\n scheme: \"vana-escrow-grant\",\n network,\n payload: signed,\n };\n return base64EncodeJson(payment);\n}\n\n/** Build a legacy grant X-PAYMENT header. */\nexport async function buildGrantPaymentHeader(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentRequired;\n config: EscrowPaymentConfig;\n}): Promise<string> {\n return buildEscrowPaymentHeader({\n ...params,\n required: {\n ...params.required,\n opType: GRANT_OP_TYPE,\n opId: params.required.grantId,\n },\n });\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction stringField(\n value: Record<string, unknown> | undefined,\n key: string,\n): string | undefined {\n const field = value?.[key];\n return typeof field === \"string\" ? field : undefined;\n}\n\nfunction isCanonicalIsoTimestamp(value: string): boolean {\n try {\n return new Date(value).toISOString() === value;\n } catch {\n return false;\n }\n}\n\n/**\n * Parse shape-validated payment response metadata echoed by a Personal Server.\n *\n * @remarks\n * This metadata is not authenticated by the gateway. It is suitable for\n * display and debugging, not as proof that a payment occurred.\n */\nexport function paymentResponseMetadataFromHeader(\n header: string | null | undefined,\n): DirectPaymentResponseMetadata | undefined {\n if (!header) return undefined;\n try {\n const result = asRecord(base64DecodeJson(header));\n const breakdown = asRecord(result?.breakdown);\n const opType = stringField(result, \"opType\");\n const opId = stringField(result, \"opId\");\n const payerAddress = stringField(result, \"payerAddress\");\n const asset = stringField(result, \"asset\");\n const amount = stringField(result, \"amount\");\n const paymentNonce = stringField(result, \"paymentNonce\");\n const registrationFee = stringField(breakdown, \"registrationFee\");\n const dataAccessFee = stringField(breakdown, \"dataAccessFee\");\n const paidAt = stringField(result, \"paidAt\");\n if (\n result?.success !== true ||\n !opType ||\n !opId ||\n !BYTES32_RE.test(opId) ||\n !payerAddress ||\n !ADDRESS_RE.test(payerAddress) ||\n !asset ||\n !ADDRESS_RE.test(asset) ||\n !amount ||\n !isUint256Decimal(amount, true) ||\n !paymentNonce ||\n !isUint256Decimal(paymentNonce, false) ||\n !registrationFee ||\n !isUint256Decimal(registrationFee, true) ||\n !dataAccessFee ||\n !isUint256Decimal(dataAccessFee, true) ||\n typeof breakdown?.registrationPaid !== \"boolean\" ||\n !paidAt ||\n !isCanonicalIsoTimestamp(paidAt)\n ) {\n return undefined;\n }\n return {\n opType,\n opId,\n asset,\n amount,\n paymentNonce,\n breakdown: {\n registrationFee,\n dataAccessFee,\n registrationPaid: breakdown.registrationPaid,\n },\n paidAt,\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * @deprecated Use {@link paymentResponseMetadataFromHeader}. A Personal\n * Server response header is untrusted metadata, not a gateway-authenticated\n * receipt.\n */\nexport function paymentReceiptFromHeader(\n header: string | null | undefined,\n): DirectPaymentResponseMetadata | undefined {\n return paymentResponseMetadataFromHeader(header);\n}\n\n/**\n * Authorize an escrow payment for a grant data-access fee.\n *\n * @param params - The payment requirement, the payer address, and escrow config.\n * @returns The gateway's {@link EscrowPayResult} as a typed\n * {@link DirectPaymentReceipt}.\n */\nexport async function authorizeGrantPayment(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentRequired;\n config: EscrowPaymentConfig;\n}): Promise<DirectPaymentReceipt> {\n return authorizeEscrowPayment({\n ...params,\n required: {\n ...params.required,\n opType: GRANT_OP_TYPE,\n opId: params.required.grantId,\n },\n });\n}\n\n/**\n * Authorize a validated grant or data-access operation through the escrow\n * gateway.\n */\nexport async function authorizeEscrowPayment(params: {\n /** Address whose escrow balance pays for the operation. */\n payerAddress: `0x${string}`;\n /** Validated operation to authorize. */\n required: PersonalServerPaymentOperation;\n /** Escrow gateway and signing configuration. */\n config: EscrowPaymentConfig;\n}): Promise<DirectPaymentReceipt> {\n const { payerAddress, config } = params;\n const signed = await signEscrowPayment(params);\n\n const result = await config.client.payForOp({\n payerAddress,\n opType: signed.message.opType,\n opId: signed.message.opId,\n asset: signed.message.asset,\n amount: signed.message.amount,\n paymentNonce: signed.message.paymentNonce,\n signature: signed.signature,\n accessRecord: signed.accessRecord,\n });\n\n return toDirectPaymentReceipt(result);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/direct/escrow-payment.ts"],"sourcesContent":["/**\n * Escrow-backed payment authorization for the Direct Data Controller.\n *\n * @remarks\n * Builds on the DPv2 escrow surface added in `protocol/escrow`. When a Personal\n * Server read returns `402 Payment Required`, the controller settles the\n * challenged operation through the escrow gateway:\n *\n * 1. Sign the challenge's `GenericPayment` EIP-712 message with the app key.\n * 2. POST it to the gateway's `/v1/escrow/pay` via {@link EscrowGatewayClient}.\n * 3. Map the gateway's {@link EscrowPayResult} into a typed\n * {@link DirectPaymentReceipt} for the caller to inspect.\n *\n * This module supports legacy `\"grant\"` operations and receipt-bound\n * `\"data_access\"` operations. It adapts the escrow `payForOp` flow to the\n * direct-read use case; it does not define its own payment scheme.\n *\n * @category Direct\n * @module direct/escrow-payment\n */\n\nimport {\n GENERIC_PAYMENT_TYPES,\n NATIVE_ASSET_ADDRESS,\n genericPaymentDomain,\n type EscrowAccessRecord,\n type EscrowPaymentClient,\n type EscrowPayResult,\n type PaymentBreakdown,\n} from \"../protocol/escrow\";\nimport type {\n DirectFeeBreakdown,\n DirectPaymentReceipt,\n DirectPaymentResponseMetadata,\n PersonalServerPaymentOperation,\n PersonalServerPaymentRequired,\n} from \"./types\";\n\n/** The escrow `GenericPayment.opType` used for grant-lifecycle payments. */\nexport const GRANT_OP_TYPE = \"grant\" as const;\n/** The escrow `GenericPayment.opType` used for receipt-bound data access. */\nexport const DATA_ACCESS_OP_TYPE = \"data_access\" as const;\n\n/**\n * EIP-712 typed-data signer (e.g. viem `account.signTypedData`).\n *\n * @remarks\n * Kept structurally minimal so any viem account/wallet client satisfies it\n * without the SDK depending on viem's exact `signTypedData` overload set.\n */\nexport type SignTypedDataFn = (args: {\n domain: ReturnType<typeof genericPaymentDomain>;\n types: typeof GENERIC_PAYMENT_TYPES;\n primaryType: \"GenericPayment\";\n message: {\n payerAddress: `0x${string}`;\n opType: string;\n opId: `0x${string}`;\n asset: `0x${string}`;\n amount: bigint;\n paymentNonce: bigint;\n };\n}) => Promise<`0x${string}`>;\n\n/** Supplies a monotonically-increasing payment nonce per payer. */\nexport type PaymentNonceSource = (\n payerAddress: string,\n) => Promise<bigint> | bigint;\n\ninterface EscrowPaymentMessage {\n payerAddress: `0x${string}`;\n opType: typeof GRANT_OP_TYPE | typeof DATA_ACCESS_OP_TYPE;\n opId: `0x${string}`;\n asset: `0x${string}`;\n amount: string;\n paymentNonce: string;\n}\n\ninterface SignedEscrowPayment {\n message: EscrowPaymentMessage;\n signature: `0x${string}`;\n accessRecord?: EscrowAccessRecord;\n}\n\ninterface X402PaymentHeader {\n x402Version: 1;\n scheme: \"vana-escrow-grant\";\n network: string;\n payload: SignedEscrowPayment;\n}\n\n/** Configuration required to sign an escrow X-PAYMENT header. */\nexport interface EscrowPaymentHeaderConfig {\n /** Deployed `DataPortabilityEscrow` contract address. */\n escrowContract: `0x${string}`;\n /** Chain id for the EIP-712 domain (1480 mainnet, 14800 moksha). */\n chainId: number;\n /** App EIP-712 signer. */\n signTypedData: SignTypedDataFn;\n /**\n * Supplies the next payment nonce for a payer. Defaults to a process-local\n * monotonic counter seeded at 1. Provide a durable source in production so\n * nonces survive restarts (the gateway rejects reused (payer, nonce) pairs).\n */\n nonceSource?: PaymentNonceSource;\n}\n\n/**\n * Escrow settlement configuration for gateway authorization.\n *\n * @remarks\n * Extends the header-signing boundary with the gateway client used by\n * {@link authorizeEscrowPayment}. Existing controller and legacy wrapper\n * callers can continue to provide this full configuration.\n */\nexport interface EscrowPaymentConfig extends EscrowPaymentHeaderConfig {\n /** Client for the gateway escrow endpoints (`/v1/escrow/*`). */\n client: EscrowPaymentClient;\n}\n\n/** Map the gateway {@link PaymentBreakdown} into the public {@link DirectFeeBreakdown}. */\nexport function toDirectFeeBreakdown(\n breakdown: PaymentBreakdown,\n): DirectFeeBreakdown {\n return {\n registrationFee: breakdown.registrationFee,\n dataAccessFee: breakdown.dataAccessFee,\n registrationPaid: breakdown.registrationPaid,\n };\n}\n\n/** Map a gateway {@link EscrowPayResult} into the public {@link DirectPaymentReceipt}. */\nexport function toDirectPaymentReceipt(\n result: EscrowPayResult,\n): DirectPaymentReceipt {\n return {\n opType: result.opType,\n opId: result.opId,\n asset: result.asset,\n amount: result.amount,\n paymentNonce: result.paymentNonce,\n breakdown: toDirectFeeBreakdown(result.breakdown),\n paidAt: result.paidAt,\n };\n}\n\n/** Default in-process monotonic nonce counter (seeded at 1 per payer). */\nexport function createDefaultNonceSource(): PaymentNonceSource {\n const counters = new Map<string, bigint>();\n return (payerAddress: string): bigint => {\n const key = payerAddress.toLowerCase();\n const next = (counters.get(key) ?? 0n) + 1n;\n counters.set(key, next);\n return next;\n };\n}\n\nconst processLocalNonceSource = createDefaultNonceSource();\nconst UINT256_MAX = (1n << 256n) - 1n;\nconst ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\nconst BYTES32_RE = /^0x[0-9a-fA-F]{64}$/;\nconst SIGNATURE_RE = /^0x[0-9a-fA-F]{130}$/;\n\nfunction isUint256Decimal(value: string, allowZero: boolean): boolean {\n const pattern = allowZero ? /^(0|[1-9]\\d*)$/ : /^[1-9]\\d*$/;\n return (\n value.length <= UINT256_MAX.toString().length &&\n pattern.test(value) &&\n BigInt(value) <= UINT256_MAX\n );\n}\n\nfunction isValidAccessRecord(record: EscrowAccessRecord): boolean {\n return (\n BYTES32_RE.test(record.dataPointId) &&\n isUint256Decimal(record.version, false) &&\n ADDRESS_RE.test(record.accessor) &&\n BYTES32_RE.test(record.recordId) &&\n SIGNATURE_RE.test(record.signature)\n );\n}\n\nfunction validateSigningOperation(\n payerAddress: `0x${string}`,\n required: PersonalServerPaymentOperation,\n): void {\n if (!ADDRESS_RE.test(payerAddress)) {\n throw new Error(\"Payment payer must be a 20-byte EVM address\");\n }\n if (!BYTES32_RE.test(required.opId)) {\n throw new Error(\"Payment operation id must be a 32-byte hex value\");\n }\n if (!ADDRESS_RE.test(required.asset || NATIVE_ASSET_ADDRESS)) {\n throw new Error(\"Payment asset must be a 20-byte EVM address\");\n }\n if (!isUint256Decimal(required.amount, true)) {\n throw new Error(\"Payment amount must be a canonical uint256 decimal\");\n }\n if (\n required.paymentNonce !== undefined &&\n !isUint256Decimal(required.paymentNonce, false)\n ) {\n throw new Error(\"Payment nonce must be a positive uint256 decimal\");\n }\n\n const accessRecord = required.accessRecord;\n if (required.opType === DATA_ACCESS_OP_TYPE) {\n if (!accessRecord || !isValidAccessRecord(accessRecord)) {\n throw new Error(\"Data-access payment requires a valid access record\");\n }\n if (required.opId.toLowerCase() !== accessRecord.recordId.toLowerCase()) {\n throw new Error(\n \"Data-access payment operation id must equal the access record id\",\n );\n }\n if (accessRecord.accessor.toLowerCase() !== payerAddress.toLowerCase()) {\n throw new Error(\n \"Data-access payment accessor must equal the payment payer address\",\n );\n }\n return;\n }\n\n if (required.amount === \"0\") {\n if (\n !accessRecord ||\n !isValidAccessRecord(accessRecord) ||\n accessRecord.accessor.toLowerCase() !== payerAddress.toLowerCase()\n ) {\n throw new Error(\n \"Zero-amount grant payments require a valid access record for the payer\",\n );\n }\n }\n}\n\nfunction base64EncodeJson(value: unknown): string {\n const bytes = new TextEncoder().encode(JSON.stringify(value));\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n\nfunction base64DecodeJson(value: string): unknown {\n const binary = atob(value);\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return JSON.parse(new TextDecoder().decode(bytes));\n}\n\nasync function signEscrowPayment(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentOperation;\n config: EscrowPaymentHeaderConfig;\n}): Promise<SignedEscrowPayment> {\n const { payerAddress, required, config } = params;\n validateSigningOperation(payerAddress, required);\n const nonceSource = config.nonceSource ?? processLocalNonceSource;\n const paymentNonce = BigInt(\n required.paymentNonce ?? (await nonceSource(payerAddress)),\n );\n const asset = (required.asset || NATIVE_ASSET_ADDRESS) as `0x${string}`;\n const opId = required.opId as `0x${string}`;\n const amount = BigInt(required.amount);\n if (amount < 0n || amount > UINT256_MAX) {\n throw new Error(\"Payment amount must be a uint256\");\n }\n if (paymentNonce <= 0n || paymentNonce > UINT256_MAX) {\n throw new Error(\"Payment nonce must be a positive uint256\");\n }\n\n const message = {\n payerAddress,\n opType: required.opType,\n opId,\n asset,\n amount,\n paymentNonce,\n };\n\n const signature = await config.signTypedData({\n domain: genericPaymentDomain(config.chainId, config.escrowContract),\n types: GENERIC_PAYMENT_TYPES,\n primaryType: \"GenericPayment\",\n message,\n });\n\n return {\n message: {\n ...message,\n amount: amount.toString(),\n paymentNonce: paymentNonce.toString(),\n },\n signature,\n ...(required.accessRecord ? { accessRecord: required.accessRecord } : {}),\n };\n}\n\n/**\n * Build the canonical X-PAYMENT header for a validated escrow operation.\n *\n * @remarks\n * Supports both legacy grant payments and receipt-bound data-access payments.\n * Signing is injected through {@link EscrowPaymentHeaderConfig.signTypedData}.\n */\nexport async function buildEscrowPaymentHeader(params: {\n /** Address whose escrow balance pays for the operation. */\n payerAddress: `0x${string}`;\n /** Validated operation parsed from the Personal Server challenge. */\n required: PersonalServerPaymentOperation;\n /** Escrow contract, chain, signer, and nonce configuration. */\n config: EscrowPaymentHeaderConfig;\n}): Promise<string> {\n const network = params.required.network ?? `vana:${params.config.chainId}`;\n if (network !== `vana:${params.config.chainId}`) {\n throw new Error(\"Payment network must match the configured chain\");\n }\n\n const signed = await signEscrowPayment(params);\n const payment: X402PaymentHeader = {\n x402Version: 1,\n scheme: \"vana-escrow-grant\",\n network,\n payload: signed,\n };\n return base64EncodeJson(payment);\n}\n\n/** Build a legacy grant X-PAYMENT header. */\nexport async function buildGrantPaymentHeader(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentRequired;\n config: EscrowPaymentConfig;\n}): Promise<string> {\n return buildEscrowPaymentHeader({\n ...params,\n required: {\n ...params.required,\n opType: GRANT_OP_TYPE,\n opId: params.required.grantId,\n },\n });\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction stringField(\n value: Record<string, unknown> | undefined,\n key: string,\n): string | undefined {\n const field = value?.[key];\n return typeof field === \"string\" ? field : undefined;\n}\n\nfunction isCanonicalIsoTimestamp(value: string): boolean {\n try {\n return new Date(value).toISOString() === value;\n } catch {\n return false;\n }\n}\n\n/**\n * Parse shape-validated payment response metadata echoed by a Personal Server.\n *\n * @remarks\n * This metadata is not authenticated by the gateway. It is suitable for\n * display and debugging, not as proof that a payment occurred.\n */\nexport function paymentResponseMetadataFromHeader(\n header: string | null | undefined,\n): DirectPaymentResponseMetadata | undefined {\n if (!header) return undefined;\n try {\n const result = asRecord(base64DecodeJson(header));\n const breakdown = asRecord(result?.breakdown);\n const opType = stringField(result, \"opType\");\n const opId = stringField(result, \"opId\");\n const payerAddress = stringField(result, \"payerAddress\");\n const asset = stringField(result, \"asset\");\n const amount = stringField(result, \"amount\");\n const paymentNonce = stringField(result, \"paymentNonce\");\n const registrationFee = stringField(breakdown, \"registrationFee\");\n const dataAccessFee = stringField(breakdown, \"dataAccessFee\");\n const paidAt = stringField(result, \"paidAt\");\n if (\n result?.success !== true ||\n !opType ||\n !opId ||\n !BYTES32_RE.test(opId) ||\n !payerAddress ||\n !ADDRESS_RE.test(payerAddress) ||\n !asset ||\n !ADDRESS_RE.test(asset) ||\n !amount ||\n !isUint256Decimal(amount, true) ||\n !paymentNonce ||\n !isUint256Decimal(paymentNonce, false) ||\n !registrationFee ||\n !isUint256Decimal(registrationFee, true) ||\n !dataAccessFee ||\n !isUint256Decimal(dataAccessFee, true) ||\n typeof breakdown?.registrationPaid !== \"boolean\" ||\n !paidAt ||\n !isCanonicalIsoTimestamp(paidAt)\n ) {\n return undefined;\n }\n return {\n opType,\n opId,\n asset,\n amount,\n paymentNonce,\n breakdown: {\n registrationFee,\n dataAccessFee,\n registrationPaid: breakdown.registrationPaid,\n },\n paidAt,\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * @deprecated Use {@link paymentResponseMetadataFromHeader}. A Personal\n * Server response header is untrusted metadata, not a gateway-authenticated\n * receipt.\n */\nexport function paymentReceiptFromHeader(\n header: string | null | undefined,\n): DirectPaymentResponseMetadata | undefined {\n return paymentResponseMetadataFromHeader(header);\n}\n\n/**\n * Authorize an escrow payment for a grant data-access fee.\n *\n * @param params - The payment requirement, the payer address, and escrow config.\n * @returns The gateway's {@link EscrowPayResult} as a typed\n * {@link DirectPaymentReceipt}.\n */\nexport async function authorizeGrantPayment(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentRequired;\n config: EscrowPaymentConfig;\n}): Promise<DirectPaymentReceipt> {\n return authorizeEscrowPayment({\n ...params,\n required: {\n ...params.required,\n opType: GRANT_OP_TYPE,\n opId: params.required.grantId,\n },\n });\n}\n\n/**\n * Authorize a validated grant or data-access operation through the escrow\n * gateway.\n */\nexport async function authorizeEscrowPayment(params: {\n /** Address whose escrow balance pays for the operation. */\n payerAddress: `0x${string}`;\n /** Validated operation to authorize. */\n required: PersonalServerPaymentOperation;\n /** Escrow gateway and signing configuration. */\n config: EscrowPaymentConfig;\n}): Promise<DirectPaymentReceipt> {\n const { payerAddress, config } = params;\n const signed = await signEscrowPayment(params);\n\n const result = await config.client.payForOp({\n payerAddress,\n opType: signed.message.opType,\n opId: signed.message.opId,\n asset: signed.message.asset,\n amount: signed.message.amount,\n paymentNonce: signed.message.paymentNonce,\n signature: signed.signature,\n accessRecord: signed.accessRecord,\n });\n\n return toDirectPaymentReceipt(result);\n}\n"],"mappings":"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","names":[]}
@@ -18,7 +18,7 @@
18
18
  * @category Direct
19
19
  * @module direct/escrow-payment
20
20
  */
21
- import { GENERIC_PAYMENT_TYPES, genericPaymentDomain, type EscrowGatewayClient, type EscrowPayResult, type PaymentBreakdown } from "../protocol/escrow.js";
21
+ import { GENERIC_PAYMENT_TYPES, genericPaymentDomain, type EscrowPaymentClient, type EscrowPayResult, type PaymentBreakdown } from "../protocol/escrow.js";
22
22
  import type { DirectFeeBreakdown, DirectPaymentReceipt, DirectPaymentResponseMetadata, PersonalServerPaymentOperation, PersonalServerPaymentRequired } from "./types.js";
23
23
  /** The escrow `GenericPayment.opType` used for grant-lifecycle payments. */
24
24
  export declare const GRANT_OP_TYPE: "grant";
@@ -71,7 +71,7 @@ export interface EscrowPaymentHeaderConfig {
71
71
  */
72
72
  export interface EscrowPaymentConfig extends EscrowPaymentHeaderConfig {
73
73
  /** Client for the gateway escrow endpoints (`/v1/escrow/*`). */
74
- client: EscrowGatewayClient;
74
+ client: EscrowPaymentClient;
75
75
  }
76
76
  /** Map the gateway {@link PaymentBreakdown} into the public {@link DirectFeeBreakdown}. */
77
77
  export declare function toDirectFeeBreakdown(breakdown: PaymentBreakdown): DirectFeeBreakdown;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/direct/escrow-payment.ts"],"sourcesContent":["/**\n * Escrow-backed payment authorization for the Direct Data Controller.\n *\n * @remarks\n * Builds on the DPv2 escrow surface added in `protocol/escrow`. When a Personal\n * Server read returns `402 Payment Required`, the controller settles the\n * challenged operation through the escrow gateway:\n *\n * 1. Sign the challenge's `GenericPayment` EIP-712 message with the app key.\n * 2. POST it to the gateway's `/v1/escrow/pay` via {@link EscrowGatewayClient}.\n * 3. Map the gateway's {@link EscrowPayResult} into a typed\n * {@link DirectPaymentReceipt} for the caller to inspect.\n *\n * This module supports legacy `\"grant\"` operations and receipt-bound\n * `\"data_access\"` operations. It adapts the escrow `payForOp` flow to the\n * direct-read use case; it does not define its own payment scheme.\n *\n * @category Direct\n * @module direct/escrow-payment\n */\n\nimport {\n GENERIC_PAYMENT_TYPES,\n NATIVE_ASSET_ADDRESS,\n genericPaymentDomain,\n type EscrowAccessRecord,\n type EscrowGatewayClient,\n type EscrowPayResult,\n type PaymentBreakdown,\n} from \"../protocol/escrow\";\nimport type {\n DirectFeeBreakdown,\n DirectPaymentReceipt,\n DirectPaymentResponseMetadata,\n PersonalServerPaymentOperation,\n PersonalServerPaymentRequired,\n} from \"./types\";\n\n/** The escrow `GenericPayment.opType` used for grant-lifecycle payments. */\nexport const GRANT_OP_TYPE = \"grant\" as const;\n/** The escrow `GenericPayment.opType` used for receipt-bound data access. */\nexport const DATA_ACCESS_OP_TYPE = \"data_access\" as const;\n\n/**\n * EIP-712 typed-data signer (e.g. viem `account.signTypedData`).\n *\n * @remarks\n * Kept structurally minimal so any viem account/wallet client satisfies it\n * without the SDK depending on viem's exact `signTypedData` overload set.\n */\nexport type SignTypedDataFn = (args: {\n domain: ReturnType<typeof genericPaymentDomain>;\n types: typeof GENERIC_PAYMENT_TYPES;\n primaryType: \"GenericPayment\";\n message: {\n payerAddress: `0x${string}`;\n opType: string;\n opId: `0x${string}`;\n asset: `0x${string}`;\n amount: bigint;\n paymentNonce: bigint;\n };\n}) => Promise<`0x${string}`>;\n\n/** Supplies a monotonically-increasing payment nonce per payer. */\nexport type PaymentNonceSource = (\n payerAddress: string,\n) => Promise<bigint> | bigint;\n\ninterface EscrowPaymentMessage {\n payerAddress: `0x${string}`;\n opType: typeof GRANT_OP_TYPE | typeof DATA_ACCESS_OP_TYPE;\n opId: `0x${string}`;\n asset: `0x${string}`;\n amount: string;\n paymentNonce: string;\n}\n\ninterface SignedEscrowPayment {\n message: EscrowPaymentMessage;\n signature: `0x${string}`;\n accessRecord?: EscrowAccessRecord;\n}\n\ninterface X402PaymentHeader {\n x402Version: 1;\n scheme: \"vana-escrow-grant\";\n network: string;\n payload: SignedEscrowPayment;\n}\n\n/** Configuration required to sign an escrow X-PAYMENT header. */\nexport interface EscrowPaymentHeaderConfig {\n /** Deployed `DataPortabilityEscrow` contract address. */\n escrowContract: `0x${string}`;\n /** Chain id for the EIP-712 domain (1480 mainnet, 14800 moksha). */\n chainId: number;\n /** App EIP-712 signer. */\n signTypedData: SignTypedDataFn;\n /**\n * Supplies the next payment nonce for a payer. Defaults to a process-local\n * monotonic counter seeded at 1. Provide a durable source in production so\n * nonces survive restarts (the gateway rejects reused (payer, nonce) pairs).\n */\n nonceSource?: PaymentNonceSource;\n}\n\n/**\n * Escrow settlement configuration for gateway authorization.\n *\n * @remarks\n * Extends the header-signing boundary with the gateway client used by\n * {@link authorizeEscrowPayment}. Existing controller and legacy wrapper\n * callers can continue to provide this full configuration.\n */\nexport interface EscrowPaymentConfig extends EscrowPaymentHeaderConfig {\n /** Client for the gateway escrow endpoints (`/v1/escrow/*`). */\n client: EscrowGatewayClient;\n}\n\n/** Map the gateway {@link PaymentBreakdown} into the public {@link DirectFeeBreakdown}. */\nexport function toDirectFeeBreakdown(\n breakdown: PaymentBreakdown,\n): DirectFeeBreakdown {\n return {\n registrationFee: breakdown.registrationFee,\n dataAccessFee: breakdown.dataAccessFee,\n registrationPaid: breakdown.registrationPaid,\n };\n}\n\n/** Map a gateway {@link EscrowPayResult} into the public {@link DirectPaymentReceipt}. */\nexport function toDirectPaymentReceipt(\n result: EscrowPayResult,\n): DirectPaymentReceipt {\n return {\n opType: result.opType,\n opId: result.opId,\n asset: result.asset,\n amount: result.amount,\n paymentNonce: result.paymentNonce,\n breakdown: toDirectFeeBreakdown(result.breakdown),\n paidAt: result.paidAt,\n };\n}\n\n/** Default in-process monotonic nonce counter (seeded at 1 per payer). */\nexport function createDefaultNonceSource(): PaymentNonceSource {\n const counters = new Map<string, bigint>();\n return (payerAddress: string): bigint => {\n const key = payerAddress.toLowerCase();\n const next = (counters.get(key) ?? 0n) + 1n;\n counters.set(key, next);\n return next;\n };\n}\n\nconst processLocalNonceSource = createDefaultNonceSource();\nconst UINT256_MAX = (1n << 256n) - 1n;\nconst ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\nconst BYTES32_RE = /^0x[0-9a-fA-F]{64}$/;\nconst SIGNATURE_RE = /^0x[0-9a-fA-F]{130}$/;\n\nfunction isUint256Decimal(value: string, allowZero: boolean): boolean {\n const pattern = allowZero ? /^(0|[1-9]\\d*)$/ : /^[1-9]\\d*$/;\n return (\n value.length <= UINT256_MAX.toString().length &&\n pattern.test(value) &&\n BigInt(value) <= UINT256_MAX\n );\n}\n\nfunction isValidAccessRecord(record: EscrowAccessRecord): boolean {\n return (\n BYTES32_RE.test(record.dataPointId) &&\n isUint256Decimal(record.version, false) &&\n ADDRESS_RE.test(record.accessor) &&\n BYTES32_RE.test(record.recordId) &&\n SIGNATURE_RE.test(record.signature)\n );\n}\n\nfunction validateSigningOperation(\n payerAddress: `0x${string}`,\n required: PersonalServerPaymentOperation,\n): void {\n if (!ADDRESS_RE.test(payerAddress)) {\n throw new Error(\"Payment payer must be a 20-byte EVM address\");\n }\n if (!BYTES32_RE.test(required.opId)) {\n throw new Error(\"Payment operation id must be a 32-byte hex value\");\n }\n if (!ADDRESS_RE.test(required.asset || NATIVE_ASSET_ADDRESS)) {\n throw new Error(\"Payment asset must be a 20-byte EVM address\");\n }\n if (!isUint256Decimal(required.amount, true)) {\n throw new Error(\"Payment amount must be a canonical uint256 decimal\");\n }\n if (\n required.paymentNonce !== undefined &&\n !isUint256Decimal(required.paymentNonce, false)\n ) {\n throw new Error(\"Payment nonce must be a positive uint256 decimal\");\n }\n\n const accessRecord = required.accessRecord;\n if (required.opType === DATA_ACCESS_OP_TYPE) {\n if (!accessRecord || !isValidAccessRecord(accessRecord)) {\n throw new Error(\"Data-access payment requires a valid access record\");\n }\n if (required.opId.toLowerCase() !== accessRecord.recordId.toLowerCase()) {\n throw new Error(\n \"Data-access payment operation id must equal the access record id\",\n );\n }\n if (accessRecord.accessor.toLowerCase() !== payerAddress.toLowerCase()) {\n throw new Error(\n \"Data-access payment accessor must equal the payment payer address\",\n );\n }\n return;\n }\n\n if (required.amount === \"0\") {\n if (\n !accessRecord ||\n !isValidAccessRecord(accessRecord) ||\n accessRecord.accessor.toLowerCase() !== payerAddress.toLowerCase()\n ) {\n throw new Error(\n \"Zero-amount grant payments require a valid access record for the payer\",\n );\n }\n }\n}\n\nfunction base64EncodeJson(value: unknown): string {\n const bytes = new TextEncoder().encode(JSON.stringify(value));\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n\nfunction base64DecodeJson(value: string): unknown {\n const binary = atob(value);\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return JSON.parse(new TextDecoder().decode(bytes));\n}\n\nasync function signEscrowPayment(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentOperation;\n config: EscrowPaymentHeaderConfig;\n}): Promise<SignedEscrowPayment> {\n const { payerAddress, required, config } = params;\n validateSigningOperation(payerAddress, required);\n const nonceSource = config.nonceSource ?? processLocalNonceSource;\n const paymentNonce = BigInt(\n required.paymentNonce ?? (await nonceSource(payerAddress)),\n );\n const asset = (required.asset || NATIVE_ASSET_ADDRESS) as `0x${string}`;\n const opId = required.opId as `0x${string}`;\n const amount = BigInt(required.amount);\n if (amount < 0n || amount > UINT256_MAX) {\n throw new Error(\"Payment amount must be a uint256\");\n }\n if (paymentNonce <= 0n || paymentNonce > UINT256_MAX) {\n throw new Error(\"Payment nonce must be a positive uint256\");\n }\n\n const message = {\n payerAddress,\n opType: required.opType,\n opId,\n asset,\n amount,\n paymentNonce,\n };\n\n const signature = await config.signTypedData({\n domain: genericPaymentDomain(config.chainId, config.escrowContract),\n types: GENERIC_PAYMENT_TYPES,\n primaryType: \"GenericPayment\",\n message,\n });\n\n return {\n message: {\n ...message,\n amount: amount.toString(),\n paymentNonce: paymentNonce.toString(),\n },\n signature,\n ...(required.accessRecord ? { accessRecord: required.accessRecord } : {}),\n };\n}\n\n/**\n * Build the canonical X-PAYMENT header for a validated escrow operation.\n *\n * @remarks\n * Supports both legacy grant payments and receipt-bound data-access payments.\n * Signing is injected through {@link EscrowPaymentHeaderConfig.signTypedData}.\n */\nexport async function buildEscrowPaymentHeader(params: {\n /** Address whose escrow balance pays for the operation. */\n payerAddress: `0x${string}`;\n /** Validated operation parsed from the Personal Server challenge. */\n required: PersonalServerPaymentOperation;\n /** Escrow contract, chain, signer, and nonce configuration. */\n config: EscrowPaymentHeaderConfig;\n}): Promise<string> {\n const network = params.required.network ?? `vana:${params.config.chainId}`;\n if (network !== `vana:${params.config.chainId}`) {\n throw new Error(\"Payment network must match the configured chain\");\n }\n\n const signed = await signEscrowPayment(params);\n const payment: X402PaymentHeader = {\n x402Version: 1,\n scheme: \"vana-escrow-grant\",\n network,\n payload: signed,\n };\n return base64EncodeJson(payment);\n}\n\n/** Build a legacy grant X-PAYMENT header. */\nexport async function buildGrantPaymentHeader(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentRequired;\n config: EscrowPaymentConfig;\n}): Promise<string> {\n return buildEscrowPaymentHeader({\n ...params,\n required: {\n ...params.required,\n opType: GRANT_OP_TYPE,\n opId: params.required.grantId,\n },\n });\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction stringField(\n value: Record<string, unknown> | undefined,\n key: string,\n): string | undefined {\n const field = value?.[key];\n return typeof field === \"string\" ? field : undefined;\n}\n\nfunction isCanonicalIsoTimestamp(value: string): boolean {\n try {\n return new Date(value).toISOString() === value;\n } catch {\n return false;\n }\n}\n\n/**\n * Parse shape-validated payment response metadata echoed by a Personal Server.\n *\n * @remarks\n * This metadata is not authenticated by the gateway. It is suitable for\n * display and debugging, not as proof that a payment occurred.\n */\nexport function paymentResponseMetadataFromHeader(\n header: string | null | undefined,\n): DirectPaymentResponseMetadata | undefined {\n if (!header) return undefined;\n try {\n const result = asRecord(base64DecodeJson(header));\n const breakdown = asRecord(result?.breakdown);\n const opType = stringField(result, \"opType\");\n const opId = stringField(result, \"opId\");\n const payerAddress = stringField(result, \"payerAddress\");\n const asset = stringField(result, \"asset\");\n const amount = stringField(result, \"amount\");\n const paymentNonce = stringField(result, \"paymentNonce\");\n const registrationFee = stringField(breakdown, \"registrationFee\");\n const dataAccessFee = stringField(breakdown, \"dataAccessFee\");\n const paidAt = stringField(result, \"paidAt\");\n if (\n result?.success !== true ||\n !opType ||\n !opId ||\n !BYTES32_RE.test(opId) ||\n !payerAddress ||\n !ADDRESS_RE.test(payerAddress) ||\n !asset ||\n !ADDRESS_RE.test(asset) ||\n !amount ||\n !isUint256Decimal(amount, true) ||\n !paymentNonce ||\n !isUint256Decimal(paymentNonce, false) ||\n !registrationFee ||\n !isUint256Decimal(registrationFee, true) ||\n !dataAccessFee ||\n !isUint256Decimal(dataAccessFee, true) ||\n typeof breakdown?.registrationPaid !== \"boolean\" ||\n !paidAt ||\n !isCanonicalIsoTimestamp(paidAt)\n ) {\n return undefined;\n }\n return {\n opType,\n opId,\n asset,\n amount,\n paymentNonce,\n breakdown: {\n registrationFee,\n dataAccessFee,\n registrationPaid: breakdown.registrationPaid,\n },\n paidAt,\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * @deprecated Use {@link paymentResponseMetadataFromHeader}. A Personal\n * Server response header is untrusted metadata, not a gateway-authenticated\n * receipt.\n */\nexport function paymentReceiptFromHeader(\n header: string | null | undefined,\n): DirectPaymentResponseMetadata | undefined {\n return paymentResponseMetadataFromHeader(header);\n}\n\n/**\n * Authorize an escrow payment for a grant data-access fee.\n *\n * @param params - The payment requirement, the payer address, and escrow config.\n * @returns The gateway's {@link EscrowPayResult} as a typed\n * {@link DirectPaymentReceipt}.\n */\nexport async function authorizeGrantPayment(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentRequired;\n config: EscrowPaymentConfig;\n}): Promise<DirectPaymentReceipt> {\n return authorizeEscrowPayment({\n ...params,\n required: {\n ...params.required,\n opType: GRANT_OP_TYPE,\n opId: params.required.grantId,\n },\n });\n}\n\n/**\n * Authorize a validated grant or data-access operation through the escrow\n * gateway.\n */\nexport async function authorizeEscrowPayment(params: {\n /** Address whose escrow balance pays for the operation. */\n payerAddress: `0x${string}`;\n /** Validated operation to authorize. */\n required: PersonalServerPaymentOperation;\n /** Escrow gateway and signing configuration. */\n config: EscrowPaymentConfig;\n}): Promise<DirectPaymentReceipt> {\n const { payerAddress, config } = params;\n const signed = await signEscrowPayment(params);\n\n const result = await config.client.payForOp({\n payerAddress,\n opType: signed.message.opType,\n opId: signed.message.opId,\n asset: signed.message.asset,\n amount: signed.message.amount,\n paymentNonce: signed.message.paymentNonce,\n signature: signed.signature,\n accessRecord: signed.accessRecord,\n });\n\n return toDirectPaymentReceipt(result);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/direct/escrow-payment.ts"],"sourcesContent":["/**\n * Escrow-backed payment authorization for the Direct Data Controller.\n *\n * @remarks\n * Builds on the DPv2 escrow surface added in `protocol/escrow`. When a Personal\n * Server read returns `402 Payment Required`, the controller settles the\n * challenged operation through the escrow gateway:\n *\n * 1. Sign the challenge's `GenericPayment` EIP-712 message with the app key.\n * 2. POST it to the gateway's `/v1/escrow/pay` via {@link EscrowGatewayClient}.\n * 3. Map the gateway's {@link EscrowPayResult} into a typed\n * {@link DirectPaymentReceipt} for the caller to inspect.\n *\n * This module supports legacy `\"grant\"` operations and receipt-bound\n * `\"data_access\"` operations. It adapts the escrow `payForOp` flow to the\n * direct-read use case; it does not define its own payment scheme.\n *\n * @category Direct\n * @module direct/escrow-payment\n */\n\nimport {\n GENERIC_PAYMENT_TYPES,\n NATIVE_ASSET_ADDRESS,\n genericPaymentDomain,\n type EscrowAccessRecord,\n type EscrowPaymentClient,\n type EscrowPayResult,\n type PaymentBreakdown,\n} from \"../protocol/escrow\";\nimport type {\n DirectFeeBreakdown,\n DirectPaymentReceipt,\n DirectPaymentResponseMetadata,\n PersonalServerPaymentOperation,\n PersonalServerPaymentRequired,\n} from \"./types\";\n\n/** The escrow `GenericPayment.opType` used for grant-lifecycle payments. */\nexport const GRANT_OP_TYPE = \"grant\" as const;\n/** The escrow `GenericPayment.opType` used for receipt-bound data access. */\nexport const DATA_ACCESS_OP_TYPE = \"data_access\" as const;\n\n/**\n * EIP-712 typed-data signer (e.g. viem `account.signTypedData`).\n *\n * @remarks\n * Kept structurally minimal so any viem account/wallet client satisfies it\n * without the SDK depending on viem's exact `signTypedData` overload set.\n */\nexport type SignTypedDataFn = (args: {\n domain: ReturnType<typeof genericPaymentDomain>;\n types: typeof GENERIC_PAYMENT_TYPES;\n primaryType: \"GenericPayment\";\n message: {\n payerAddress: `0x${string}`;\n opType: string;\n opId: `0x${string}`;\n asset: `0x${string}`;\n amount: bigint;\n paymentNonce: bigint;\n };\n}) => Promise<`0x${string}`>;\n\n/** Supplies a monotonically-increasing payment nonce per payer. */\nexport type PaymentNonceSource = (\n payerAddress: string,\n) => Promise<bigint> | bigint;\n\ninterface EscrowPaymentMessage {\n payerAddress: `0x${string}`;\n opType: typeof GRANT_OP_TYPE | typeof DATA_ACCESS_OP_TYPE;\n opId: `0x${string}`;\n asset: `0x${string}`;\n amount: string;\n paymentNonce: string;\n}\n\ninterface SignedEscrowPayment {\n message: EscrowPaymentMessage;\n signature: `0x${string}`;\n accessRecord?: EscrowAccessRecord;\n}\n\ninterface X402PaymentHeader {\n x402Version: 1;\n scheme: \"vana-escrow-grant\";\n network: string;\n payload: SignedEscrowPayment;\n}\n\n/** Configuration required to sign an escrow X-PAYMENT header. */\nexport interface EscrowPaymentHeaderConfig {\n /** Deployed `DataPortabilityEscrow` contract address. */\n escrowContract: `0x${string}`;\n /** Chain id for the EIP-712 domain (1480 mainnet, 14800 moksha). */\n chainId: number;\n /** App EIP-712 signer. */\n signTypedData: SignTypedDataFn;\n /**\n * Supplies the next payment nonce for a payer. Defaults to a process-local\n * monotonic counter seeded at 1. Provide a durable source in production so\n * nonces survive restarts (the gateway rejects reused (payer, nonce) pairs).\n */\n nonceSource?: PaymentNonceSource;\n}\n\n/**\n * Escrow settlement configuration for gateway authorization.\n *\n * @remarks\n * Extends the header-signing boundary with the gateway client used by\n * {@link authorizeEscrowPayment}. Existing controller and legacy wrapper\n * callers can continue to provide this full configuration.\n */\nexport interface EscrowPaymentConfig extends EscrowPaymentHeaderConfig {\n /** Client for the gateway escrow endpoints (`/v1/escrow/*`). */\n client: EscrowPaymentClient;\n}\n\n/** Map the gateway {@link PaymentBreakdown} into the public {@link DirectFeeBreakdown}. */\nexport function toDirectFeeBreakdown(\n breakdown: PaymentBreakdown,\n): DirectFeeBreakdown {\n return {\n registrationFee: breakdown.registrationFee,\n dataAccessFee: breakdown.dataAccessFee,\n registrationPaid: breakdown.registrationPaid,\n };\n}\n\n/** Map a gateway {@link EscrowPayResult} into the public {@link DirectPaymentReceipt}. */\nexport function toDirectPaymentReceipt(\n result: EscrowPayResult,\n): DirectPaymentReceipt {\n return {\n opType: result.opType,\n opId: result.opId,\n asset: result.asset,\n amount: result.amount,\n paymentNonce: result.paymentNonce,\n breakdown: toDirectFeeBreakdown(result.breakdown),\n paidAt: result.paidAt,\n };\n}\n\n/** Default in-process monotonic nonce counter (seeded at 1 per payer). */\nexport function createDefaultNonceSource(): PaymentNonceSource {\n const counters = new Map<string, bigint>();\n return (payerAddress: string): bigint => {\n const key = payerAddress.toLowerCase();\n const next = (counters.get(key) ?? 0n) + 1n;\n counters.set(key, next);\n return next;\n };\n}\n\nconst processLocalNonceSource = createDefaultNonceSource();\nconst UINT256_MAX = (1n << 256n) - 1n;\nconst ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\nconst BYTES32_RE = /^0x[0-9a-fA-F]{64}$/;\nconst SIGNATURE_RE = /^0x[0-9a-fA-F]{130}$/;\n\nfunction isUint256Decimal(value: string, allowZero: boolean): boolean {\n const pattern = allowZero ? /^(0|[1-9]\\d*)$/ : /^[1-9]\\d*$/;\n return (\n value.length <= UINT256_MAX.toString().length &&\n pattern.test(value) &&\n BigInt(value) <= UINT256_MAX\n );\n}\n\nfunction isValidAccessRecord(record: EscrowAccessRecord): boolean {\n return (\n BYTES32_RE.test(record.dataPointId) &&\n isUint256Decimal(record.version, false) &&\n ADDRESS_RE.test(record.accessor) &&\n BYTES32_RE.test(record.recordId) &&\n SIGNATURE_RE.test(record.signature)\n );\n}\n\nfunction validateSigningOperation(\n payerAddress: `0x${string}`,\n required: PersonalServerPaymentOperation,\n): void {\n if (!ADDRESS_RE.test(payerAddress)) {\n throw new Error(\"Payment payer must be a 20-byte EVM address\");\n }\n if (!BYTES32_RE.test(required.opId)) {\n throw new Error(\"Payment operation id must be a 32-byte hex value\");\n }\n if (!ADDRESS_RE.test(required.asset || NATIVE_ASSET_ADDRESS)) {\n throw new Error(\"Payment asset must be a 20-byte EVM address\");\n }\n if (!isUint256Decimal(required.amount, true)) {\n throw new Error(\"Payment amount must be a canonical uint256 decimal\");\n }\n if (\n required.paymentNonce !== undefined &&\n !isUint256Decimal(required.paymentNonce, false)\n ) {\n throw new Error(\"Payment nonce must be a positive uint256 decimal\");\n }\n\n const accessRecord = required.accessRecord;\n if (required.opType === DATA_ACCESS_OP_TYPE) {\n if (!accessRecord || !isValidAccessRecord(accessRecord)) {\n throw new Error(\"Data-access payment requires a valid access record\");\n }\n if (required.opId.toLowerCase() !== accessRecord.recordId.toLowerCase()) {\n throw new Error(\n \"Data-access payment operation id must equal the access record id\",\n );\n }\n if (accessRecord.accessor.toLowerCase() !== payerAddress.toLowerCase()) {\n throw new Error(\n \"Data-access payment accessor must equal the payment payer address\",\n );\n }\n return;\n }\n\n if (required.amount === \"0\") {\n if (\n !accessRecord ||\n !isValidAccessRecord(accessRecord) ||\n accessRecord.accessor.toLowerCase() !== payerAddress.toLowerCase()\n ) {\n throw new Error(\n \"Zero-amount grant payments require a valid access record for the payer\",\n );\n }\n }\n}\n\nfunction base64EncodeJson(value: unknown): string {\n const bytes = new TextEncoder().encode(JSON.stringify(value));\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n\nfunction base64DecodeJson(value: string): unknown {\n const binary = atob(value);\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return JSON.parse(new TextDecoder().decode(bytes));\n}\n\nasync function signEscrowPayment(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentOperation;\n config: EscrowPaymentHeaderConfig;\n}): Promise<SignedEscrowPayment> {\n const { payerAddress, required, config } = params;\n validateSigningOperation(payerAddress, required);\n const nonceSource = config.nonceSource ?? processLocalNonceSource;\n const paymentNonce = BigInt(\n required.paymentNonce ?? (await nonceSource(payerAddress)),\n );\n const asset = (required.asset || NATIVE_ASSET_ADDRESS) as `0x${string}`;\n const opId = required.opId as `0x${string}`;\n const amount = BigInt(required.amount);\n if (amount < 0n || amount > UINT256_MAX) {\n throw new Error(\"Payment amount must be a uint256\");\n }\n if (paymentNonce <= 0n || paymentNonce > UINT256_MAX) {\n throw new Error(\"Payment nonce must be a positive uint256\");\n }\n\n const message = {\n payerAddress,\n opType: required.opType,\n opId,\n asset,\n amount,\n paymentNonce,\n };\n\n const signature = await config.signTypedData({\n domain: genericPaymentDomain(config.chainId, config.escrowContract),\n types: GENERIC_PAYMENT_TYPES,\n primaryType: \"GenericPayment\",\n message,\n });\n\n return {\n message: {\n ...message,\n amount: amount.toString(),\n paymentNonce: paymentNonce.toString(),\n },\n signature,\n ...(required.accessRecord ? { accessRecord: required.accessRecord } : {}),\n };\n}\n\n/**\n * Build the canonical X-PAYMENT header for a validated escrow operation.\n *\n * @remarks\n * Supports both legacy grant payments and receipt-bound data-access payments.\n * Signing is injected through {@link EscrowPaymentHeaderConfig.signTypedData}.\n */\nexport async function buildEscrowPaymentHeader(params: {\n /** Address whose escrow balance pays for the operation. */\n payerAddress: `0x${string}`;\n /** Validated operation parsed from the Personal Server challenge. */\n required: PersonalServerPaymentOperation;\n /** Escrow contract, chain, signer, and nonce configuration. */\n config: EscrowPaymentHeaderConfig;\n}): Promise<string> {\n const network = params.required.network ?? `vana:${params.config.chainId}`;\n if (network !== `vana:${params.config.chainId}`) {\n throw new Error(\"Payment network must match the configured chain\");\n }\n\n const signed = await signEscrowPayment(params);\n const payment: X402PaymentHeader = {\n x402Version: 1,\n scheme: \"vana-escrow-grant\",\n network,\n payload: signed,\n };\n return base64EncodeJson(payment);\n}\n\n/** Build a legacy grant X-PAYMENT header. */\nexport async function buildGrantPaymentHeader(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentRequired;\n config: EscrowPaymentConfig;\n}): Promise<string> {\n return buildEscrowPaymentHeader({\n ...params,\n required: {\n ...params.required,\n opType: GRANT_OP_TYPE,\n opId: params.required.grantId,\n },\n });\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction stringField(\n value: Record<string, unknown> | undefined,\n key: string,\n): string | undefined {\n const field = value?.[key];\n return typeof field === \"string\" ? field : undefined;\n}\n\nfunction isCanonicalIsoTimestamp(value: string): boolean {\n try {\n return new Date(value).toISOString() === value;\n } catch {\n return false;\n }\n}\n\n/**\n * Parse shape-validated payment response metadata echoed by a Personal Server.\n *\n * @remarks\n * This metadata is not authenticated by the gateway. It is suitable for\n * display and debugging, not as proof that a payment occurred.\n */\nexport function paymentResponseMetadataFromHeader(\n header: string | null | undefined,\n): DirectPaymentResponseMetadata | undefined {\n if (!header) return undefined;\n try {\n const result = asRecord(base64DecodeJson(header));\n const breakdown = asRecord(result?.breakdown);\n const opType = stringField(result, \"opType\");\n const opId = stringField(result, \"opId\");\n const payerAddress = stringField(result, \"payerAddress\");\n const asset = stringField(result, \"asset\");\n const amount = stringField(result, \"amount\");\n const paymentNonce = stringField(result, \"paymentNonce\");\n const registrationFee = stringField(breakdown, \"registrationFee\");\n const dataAccessFee = stringField(breakdown, \"dataAccessFee\");\n const paidAt = stringField(result, \"paidAt\");\n if (\n result?.success !== true ||\n !opType ||\n !opId ||\n !BYTES32_RE.test(opId) ||\n !payerAddress ||\n !ADDRESS_RE.test(payerAddress) ||\n !asset ||\n !ADDRESS_RE.test(asset) ||\n !amount ||\n !isUint256Decimal(amount, true) ||\n !paymentNonce ||\n !isUint256Decimal(paymentNonce, false) ||\n !registrationFee ||\n !isUint256Decimal(registrationFee, true) ||\n !dataAccessFee ||\n !isUint256Decimal(dataAccessFee, true) ||\n typeof breakdown?.registrationPaid !== \"boolean\" ||\n !paidAt ||\n !isCanonicalIsoTimestamp(paidAt)\n ) {\n return undefined;\n }\n return {\n opType,\n opId,\n asset,\n amount,\n paymentNonce,\n breakdown: {\n registrationFee,\n dataAccessFee,\n registrationPaid: breakdown.registrationPaid,\n },\n paidAt,\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * @deprecated Use {@link paymentResponseMetadataFromHeader}. A Personal\n * Server response header is untrusted metadata, not a gateway-authenticated\n * receipt.\n */\nexport function paymentReceiptFromHeader(\n header: string | null | undefined,\n): DirectPaymentResponseMetadata | undefined {\n return paymentResponseMetadataFromHeader(header);\n}\n\n/**\n * Authorize an escrow payment for a grant data-access fee.\n *\n * @param params - The payment requirement, the payer address, and escrow config.\n * @returns The gateway's {@link EscrowPayResult} as a typed\n * {@link DirectPaymentReceipt}.\n */\nexport async function authorizeGrantPayment(params: {\n payerAddress: `0x${string}`;\n required: PersonalServerPaymentRequired;\n config: EscrowPaymentConfig;\n}): Promise<DirectPaymentReceipt> {\n return authorizeEscrowPayment({\n ...params,\n required: {\n ...params.required,\n opType: GRANT_OP_TYPE,\n opId: params.required.grantId,\n },\n });\n}\n\n/**\n * Authorize a validated grant or data-access operation through the escrow\n * gateway.\n */\nexport async function authorizeEscrowPayment(params: {\n /** Address whose escrow balance pays for the operation. */\n payerAddress: `0x${string}`;\n /** Validated operation to authorize. */\n required: PersonalServerPaymentOperation;\n /** Escrow gateway and signing configuration. */\n config: EscrowPaymentConfig;\n}): Promise<DirectPaymentReceipt> {\n const { payerAddress, config } = params;\n const signed = await signEscrowPayment(params);\n\n const result = await config.client.payForOp({\n payerAddress,\n opType: signed.message.opType,\n opId: signed.message.opId,\n asset: signed.message.asset,\n amount: signed.message.amount,\n paymentNonce: signed.message.paymentNonce,\n signature: signed.signature,\n accessRecord: signed.accessRecord,\n });\n\n return toDirectPaymentReceipt(result);\n}\n"],"mappings":"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","names":[]}
@@ -36,8 +36,8 @@ export { encryptWithPassword, decryptWithPassword, } from "./crypto/envelope/ope
36
36
  export { parseWeb3SignedHeader, verifyWeb3Signed, type Web3SignedPayload, type VerifiedAuth, } from "./auth/web3-signed.js";
37
37
  export { buildWeb3SignedHeader, computeBodyHash, type Web3SignedSignFn, } from "./auth/web3-signed-builder.js";
38
38
  export { MissingAuthError, InvalidSignatureError, ExpiredTokenError, } from "./auth/errors.js";
39
- export { NATIVE_VANA_ASSET, dataRegistryDomain, grantRegistrationDomain, grantRevocationDomain, serverRegistrationDomain, builderRegistrationDomain, escrowPaymentDomain, GRANT_REGISTRATION_TYPES, GRANT_REVOCATION_TYPES, SERVER_REGISTRATION_TYPES, BUILDER_REGISTRATION_TYPES, ADD_DATA_TYPES, RECORD_DATA_ACCESS_TYPES, type DataPortabilityContracts, type DataPortabilityGatewayConfig, type GrantRegistrationMessage, type GrantRevocationMessage, type ServerRegistrationMessage, type BuilderRegistrationMessage, type AddDataMessage, type RecordDataAccessMessage, } from "./protocol/eip712.js";
40
- export { ENCLAVE_IDENTITY_EVIDENCE_VERSION, USER_PS_ID_DOMAIN, ENCLAVE_WALLET_PURPOSE, MASTER_SIGNATURE_DELIVERY_VERSION, SEALED_ENVELOPE_VERSION, ENCLAVE_TRUST_ANCHORS, userPsId, appRootPreimage, kmsIssuedPreimage, verifyEnclaveIdentityEvidence, buildMasterSignatureDelivery, encryptMasterSignatureDelivery, type UserPsId, type EnclaveIdentityEvidence, type IdentityRequest, type IdentityState, type IdentityResponse, type IdentityRegistrationRequest, type IdentityRegistrationResponse, type MasterSignatureDelivery, type SealedSecretSubmission, type SealedSecretResponse, type AesGcmBox, type SealedEnvelope, type EnclaveTrustAnchors, } from "./protocol/identity.js";
39
+ export { NATIVE_VANA_ASSET, dataRegistryDomain, grantRegistrationDomain, grantRevocationDomain, serverRegistrationDomain, builderRegistrationDomain, escrowPaymentDomain, withdrawAuthorizationDomain, buildWithdrawAuthorizationTypedData, GRANT_REGISTRATION_TYPES, GRANT_REVOCATION_TYPES, SERVER_REGISTRATION_TYPES, BUILDER_REGISTRATION_TYPES, ADD_DATA_TYPES, RECORD_DATA_ACCESS_TYPES, WITHDRAW_AUTHORIZATION_TYPES, type DataPortabilityContracts, type DataPortabilityGatewayConfig, type GrantRegistrationMessage, type GrantRevocationMessage, type ServerRegistrationMessage, type BuilderRegistrationMessage, type AddDataMessage, type RecordDataAccessMessage, type WithdrawAuthorizationMessage, } from "./protocol/eip712.js";
40
+ export { ENCLAVE_IDENTITY_EVIDENCE_VERSION, USER_PS_ID_DOMAIN, ENCLAVE_WALLET_PURPOSE, MASTER_SIGNATURE_DELIVERY_VERSION, MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS, SEALED_ENVELOPE_VERSION, ENCLAVE_TRUST_ANCHORS, userPsId, appRootPreimage, kmsIssuedPreimage, verifyEnclaveIdentityEvidence, buildMasterSignatureDelivery, encryptMasterSignatureDelivery, type UserPsId, type EnclaveIdentityEvidence, type ExpectedIdentity, type IdentityRequest, type IdentityState, type IdentityResponse, type IdentityRegistrationRequest, type IdentityRegistrationResponse, type MasterSignatureDelivery, type SealedSecretSubmission, type SealedSecretResponse, type AesGcmBox, type SealedEnvelope, type EnclaveTrustAnchors, } from "./protocol/identity.js";
41
41
  export { PERSONAL_SERVER_REGISTRATION_DEFAULT_CHAIN_ID, PERSONAL_SERVER_REGISTRATION_DEFAULT_VERIFYING_CONTRACT, personalServerRegistrationDomain, createViemPersonalServerRegistrationSigner, buildPersonalServerRegistrationTypedData, buildPersonalServerRegistrationSignature, registerPersonalServerSignature, type PersonalServerRegistrationTypedData, type PersonalServerRegistrationSigner, type PersonalServerRegistrationDomainInput, type ViemPersonalServerRegistrationWalletClient, type ViemPersonalServerRegistrationSignerSource, type BuildPersonalServerRegistrationTypedDataInput, type BuildPersonalServerRegistrationSignatureInput, type PersonalServerRegistrationSignature, } from "./protocol/personal-server-registration.js";
42
42
  export { PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION, PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE, PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX, buildPersonalServerLiteOwnerBindingMessage, createViemPersonalServerLiteOwnerBindingSigner, buildPersonalServerLiteOwnerBindingSignature, signPersonalServerLiteOwnerBinding, type PersonalServerLiteOwnerBindingPurpose, type PersonalServerLiteOwnerBindingMessage, type PersonalServerLiteOwnerBindingSigner, type ViemPersonalServerLiteOwnerBindingWalletClient, type ViemPersonalServerLiteOwnerBindingSignerSource, type BuildPersonalServerLiteOwnerBindingSignatureInput, type PersonalServerLiteOwnerBindingSignature, } from "./personal-server-lite/owner-binding.js";
43
43
  export { ACCOUNT_PERSONAL_SERVER_REGISTRATION_INTENT, AccountPersonalServerRegistrationError, signPersonalServerRegistrationWithAccount, type AccountPersonalServerRegistrationIntent, type AccountPersonalServerRegistrationSignature, type AccountPersonalServerRegistrationStatus, type AccountPersonalServerRegistrationRequest, type AccountPersonalServerRegistrationConfig, type AccountSignedPersonalServerRegistration, type AccountConfirmationRequiredPersonalServerRegistration, type AccountFallbackSignedPersonalServerRegistration, type AccountPersonalServerRegistrationResult, } from "./account/personal-server-registration.js";
@@ -57,5 +57,5 @@ export { DERIVATIVE_STATUS_PATH, DEFAULT_DERIVATIVE_STATUS_TIMEOUT_MS, DEFAULT_D
57
57
  export { deriveDataPointId, isDataPointId, scopeNamespace, derivedScopeViolatesNaming, assertDerivedScopeNaming, isRedactedLineageNode, personalServerLineagePath, gatewayLineagePath, getLineage, getPersonalServerLineage, getGatewayLineage, LineageNodeSchema, RedactedLineageNodeSchema, LineageEntrySchema, LineageGraphSchema, type LineageNode, type RedactedLineageNode, type LineageEntry, type LineageGraph, type LineageReadResult, type PersonalServerLineageParams, type GatewayLineageParams, type GetLineageParams, } from "./protocol/lineage.js";
58
58
  export { DataFileEnvelopeSchema, createDataFileEnvelope, IngestResponseSchema, type DataFileEnvelope, type IngestResponse, } from "./protocol/data-file.js";
59
59
  export { createGatewayClient, type GatewayEnvelope, type GatewayProof, type Builder, type Schema, type ServerInfo, type OwnerServerRecord, type OwnerServersResult, type GatewayGrantFee, type GatewayGrantStatus, type GatewayGrantResponse, type GrantListItem, type DataPointRecord, type DataPointListResult, type ListDataPointsOptions, type RegisterServerParams, type RegisterServerResult, type RegisterBuilderParams, type RegisterBuilderResult, type RegisterDataPointParams, type RegisterDataPointResult, type GetDataPointOptions, type DeleteDataPointParams, type DeleteDataPointResult, type CreateGrantParams, type RevokeGrantParams, type AccessRecord, type PayForOperationParams, type PayForOperationResult, type SettleOpType, type SettleItem, type SettlePromoteResult, type SettleReconcileItem, type SettleParams, type SettleResult, type GatewayClient, } from "./protocol/gateway.js";
60
- export { createEscrowGatewayClient, genericPaymentDomain, GENERIC_PAYMENT_TYPES, ESCROW_DEPOSIT_ABI, NATIVE_ASSET_ADDRESS, type GenericPaymentMessage, type EscrowBalanceEntry, type EscrowBalanceResult, type EscrowBalanceSyncResult, type DepositSubmissionResult, type PaymentBreakdown, type EscrowPayResult, type SubmitDepositParams, type PayForOpParams, type EscrowGatewayClient, type SubmittedDepositEntry, type FinalizedDepositEntry, type FailedDepositEntry, } from "./protocol/escrow.js";
60
+ export { createEscrowGatewayClient, genericPaymentDomain, GENERIC_PAYMENT_TYPES, ESCROW_DEPOSIT_ABI, NATIVE_ASSET_ADDRESS, type GenericPaymentMessage, type EscrowBalanceEntry, type EscrowBalanceResult, type EscrowBalanceSyncResult, type DepositSubmissionResult, type PaymentBreakdown, type EscrowPayResult, EscrowWithdrawalLifecycleError, EscrowWithdrawalRejectionError, type EscrowPaymentClient, type EscrowWithdrawalFailureResult, type EscrowWithdrawalRejectedResult, type EscrowWithdrawalRejectionCode, type EscrowWithdrawalSubmittedResult, type EscrowWithdrawalSubmittedWithoutTransaction, type EscrowWithdrawalSubmittedWithTransaction, type EscrowWithdrawalSettledResult, type EscrowWithdrawalResult, type SubmitDepositParams, type PayForOpParams, type WithdrawFromEscrowParams, type WithdrawNonceResponse, type EscrowGatewayClient, type SubmittedDepositEntry, type FinalizedDepositEntry, type FailedDepositEntry, } from "./protocol/escrow.js";
61
61
  export { PSError, parsePSError, type PSErrorCode } from "./types/ps-errors.js";