@t402/cosmos 2.4.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,10 +22,10 @@ Three main components:
22
22
 
23
23
  ## Supported Networks
24
24
 
25
- | Network | CAIP-2 Identifier | USDC Denomination | Bech32 Prefix | Status |
26
- | -------------- | ------------------ | ----------------- | ------------- | ---------- |
27
- | Noble Mainnet | `cosmos:noble-1` | `uusdc` | `noble` | Production |
28
- | Noble Testnet | `cosmos:grand-1` | `uusdc` | `noble` | Testnet |
25
+ | Network | CAIP-2 Identifier | USDC Denomination | Bech32 Prefix | Status |
26
+ | ------------- | ----------------- | ----------------- | ------------- | ---------- |
27
+ | Noble Mainnet | `cosmos:noble-1` | `uusdc` | `noble` | Production |
28
+ | Noble Testnet | `cosmos:grand-1` | `uusdc` | `noble` | Testnet |
29
29
 
30
30
  ## Package Exports
31
31
 
@@ -1,5 +1,5 @@
1
1
  import { SchemeNetworkClient, PaymentRequirements, PaymentPayload } from '@t402/core/types';
2
- import { d as ClientCosmosSigner } from '../../types-CgseoctH.js';
2
+ import { C as ClientCosmosSigner } from '../../types-27CIV52j.js';
3
3
 
4
4
  /**
5
5
  * Cosmos Client Scheme Implementation - Exact Direct
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/exact-direct/client/index.ts","../../../../src/constants.ts","../../../../src/utils.ts","../../../../src/exact-direct/client/scheme.ts"],"sourcesContent":["/**\n * Cosmos Exact-Direct Client Exports\n */\n\nexport { ExactDirectCosmosClient, type ExactDirectCosmosClientConfig } from \"./scheme.js\";\n","/**\n * Cosmos Network Constants\n *\n * This module provides constants for Cosmos blockchain integration including:\n * - CAIP-2 network identifiers (Noble chain)\n * - RPC and REST endpoints\n * - Bech32 prefix configuration\n * - USDC denomination and gas parameters\n */\n\n/**\n * CAIP-2 Network Identifiers for Cosmos (Noble)\n */\nexport const NOBLE_MAINNET_CAIP2 = \"cosmos:noble-1\";\nexport const NOBLE_TESTNET_CAIP2 = \"cosmos:grand-1\";\n\n/**\n * Supported Cosmos networks\n */\nexport const COSMOS_NETWORKS = [NOBLE_MAINNET_CAIP2, NOBLE_TESTNET_CAIP2] as const;\n\nexport type CosmosNetwork = (typeof COSMOS_NETWORKS)[number];\n\n/**\n * Default RPC endpoints\n */\nexport const NOBLE_MAINNET_RPC = \"https://noble-rpc.polkachu.com\";\nexport const NOBLE_TESTNET_RPC = \"https://rpc.testnet.noble.strange.love\";\n\n/**\n * Default REST endpoints\n */\nexport const NOBLE_MAINNET_REST = \"https://noble-api.polkachu.com\";\nexport const NOBLE_TESTNET_REST = \"https://api.testnet.noble.strange.love\";\n\n/**\n * Network RPC endpoint mapping\n */\nexport const NETWORK_RPC_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_RPC,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_RPC,\n};\n\n/**\n * Network REST endpoint mapping\n */\nexport const NETWORK_REST_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_REST,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_REST,\n};\n\n/**\n * Bech32 prefix for Noble addresses\n */\nexport const NOBLE_BECH32_PREFIX = \"noble\";\n\n/**\n * USDC denomination on Noble\n * uusdc = micro-USDC (1 USDC = 1,000,000 uusdc)\n */\nexport const USDC_DENOM = \"uusdc\";\n\n/**\n * Default gas parameters\n */\nexport const DEFAULT_GAS_LIMIT = 200000;\nexport const DEFAULT_GAS_PRICE = \"0.025uusdc\";\nexport const DEFAULT_FEE_AMOUNT = \"5000\"; // 0.005 USDC\n\n/**\n * Cosmos message type for bank send\n */\nexport const MSG_TYPE_SEND = \"/cosmos.bank.v1beta1.MsgSend\";\n\n/**\n * Scheme identifier for exact-direct payments\n */\nexport const SCHEME_EXACT_DIRECT = \"exact-direct\";\n\n/**\n * Maximum transaction age to accept (in milliseconds)\n */\nexport const MAX_TRANSACTION_AGE = 5 * 60 * 1000; // 5 minutes\n\n/**\n * CAIP-2 namespace for Cosmos\n */\nexport const COSMOS_CAIP2_NAMESPACE = \"cosmos\";\n","/**\n * Cosmos Utility Functions\n *\n * Helper functions for Cosmos address validation, network normalization,\n * and amount conversion.\n */\n\nimport {\n COSMOS_CAIP2_NAMESPACE,\n NOBLE_BECH32_PREFIX,\n NETWORK_RPC_ENDPOINTS,\n NETWORK_REST_ENDPOINTS,\n type CosmosNetwork,\n} from \"./constants.js\";\n\n/**\n * Normalize a network identifier to CAIP-2 format\n * @param network - Network identifier (e.g., \"noble-1\", \"cosmos:noble-1\")\n * @returns CAIP-2 formatted network identifier\n */\nexport function normalizeNetwork(network: string): CosmosNetwork {\n // Already in CAIP-2 format\n if (network.startsWith(`${COSMOS_CAIP2_NAMESPACE}:`)) {\n return network as CosmosNetwork;\n }\n // Convert shorthand to CAIP-2\n return `${COSMOS_CAIP2_NAMESPACE}:${network}` as CosmosNetwork;\n}\n\n/**\n * Extract network ID from CAIP-2 identifier\n * @param network - CAIP-2 network identifier\n * @returns Network ID (e.g., \"noble-1\")\n */\nexport function extractNetworkId(network: string): string {\n if (network.includes(\":\")) {\n return network.split(\":\")[1];\n }\n return network;\n}\n\n/**\n * Validate a Cosmos bech32 address with Noble prefix\n * Checks that the address starts with the \"noble\" prefix followed by \"1\"\n * @param address - Address to validate\n * @returns Whether the address is valid\n */\nexport function isValidAddress(address: string): boolean {\n if (!address || address.length < 10) {\n return false;\n }\n return address.startsWith(`${NOBLE_BECH32_PREFIX}1`);\n}\n\n/**\n * Get RPC endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns RPC endpoint URL\n */\nexport function getRpcEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_RPC_ENDPOINTS[normalizedNetwork] || NETWORK_RPC_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Get REST endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns REST endpoint URL\n */\nexport function getRestEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_REST_ENDPOINTS[normalizedNetwork] || NETWORK_REST_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Convert decimal amount to token units (atomic units)\n * @param decimalAmount - Amount with decimals (e.g., \"1.50\")\n * @param decimals - Token decimals\n * @returns Amount in smallest units\n */\nexport function toAtomicUnits(decimalAmount: string | number, decimals: number): bigint {\n const amount = typeof decimalAmount === \"string\" ? parseFloat(decimalAmount) : decimalAmount;\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const multiplier = 10 ** decimals;\n return BigInt(Math.floor(amount * multiplier));\n}\n\n/**\n * Format amount for display (with decimals)\n * @param amount - Amount in smallest units\n * @param decimals - Number of decimal places\n * @returns Formatted amount string\n */\nexport function formatAmount(amount: bigint, decimals: number): string {\n const divisor = BigInt(10 ** decimals);\n const whole = amount / divisor;\n const remainder = amount % divisor;\n const decimal = remainder.toString().padStart(decimals, \"0\").slice(0, 2);\n return `${whole}.${decimal}`;\n}\n\n/**\n * Get the list of supported networks\n * @returns Array of CAIP-2 network identifiers\n */\nexport function getSupportedNetworks(): string[] {\n return Object.keys(NETWORK_RPC_ENDPOINTS);\n}\n","/**\n * Cosmos Client Scheme Implementation - Exact Direct\n *\n * Creates payment payloads for Cosmos MsgSend transfers using the exact-direct scheme.\n * In this scheme, the client executes the bank send directly and provides\n * the transaction hash as proof of payment.\n */\n\nimport type { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport type { ClientCosmosSigner, ExactDirectCosmosPayload } from \"../../types.js\";\nimport { SCHEME_EXACT_DIRECT, USDC_DENOM } from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\n\n/**\n * Configuration for ExactDirectCosmosClient\n */\nexport interface ExactDirectCosmosClientConfig {\n /** Override the default denomination */\n denom?: string;\n}\n\n/**\n * Cosmos client implementation for the Exact-Direct payment scheme.\n *\n * Executes a Cosmos MsgSend and returns the transaction hash as proof.\n */\nexport class ExactDirectCosmosClient implements SchemeNetworkClient {\n readonly scheme = SCHEME_EXACT_DIRECT;\n\n /**\n * Creates a new ExactDirectCosmosClient instance.\n *\n * @param signer - The Cosmos signer for client operations\n * @param config - Optional configuration overrides\n */\n constructor(\n private readonly signer: ClientCosmosSigner,\n private readonly config: ExactDirectCosmosClientConfig = {},\n ) {}\n\n /**\n * Creates a payment payload by executing the transfer.\n *\n * Unlike other schemes where the client creates a signed message for\n * the facilitator to execute, the exact-direct scheme has the client\n * execute the transfer directly. The transaction hash is then used\n * as proof of payment.\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload with transaction hash\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Normalize and validate network\n const network = normalizeNetwork(paymentRequirements.network);\n\n // Validate required fields\n if (!paymentRequirements.payTo) {\n throw new Error(\"PayTo address is required\");\n }\n if (!paymentRequirements.amount) {\n throw new Error(\"Amount is required\");\n }\n\n // Validate addresses\n if (!isValidAddress(paymentRequirements.payTo)) {\n throw new Error(`Invalid recipient address: ${paymentRequirements.payTo}`);\n }\n if (!isValidAddress(this.signer.address)) {\n throw new Error(`Invalid sender address: ${this.signer.address}`);\n }\n\n const recipient = paymentRequirements.payTo;\n const amount = paymentRequirements.amount;\n\n // Determine denomination from extra field, config, or default\n const denom =\n (paymentRequirements.extra?.denom as string) || this.config.denom || USDC_DENOM;\n\n // Execute the transfer\n const txHash = await this.signer.sendTokens(network, recipient, amount, denom);\n\n // Build the payload\n const payload: ExactDirectCosmosPayload = {\n txHash,\n from: this.signer.address,\n to: recipient,\n amount: amount,\n denom,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACaO,IAAM,sBAAsB;AAC5B,IAAM,sBAAsB;AAY5B,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAK1B,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAK3B,IAAM,wBAAgD;AAAA,EAC3D,CAAC,mBAAmB,GAAG;AAAA,EACvB,CAAC,mBAAmB,GAAG;AACzB;AAKO,IAAM,yBAAiD;AAAA,EAC5D,CAAC,mBAAmB,GAAG;AAAA,EACvB,CAAC,mBAAmB,GAAG;AACzB;AAKO,IAAM,sBAAsB;AAM5B,IAAM,aAAa;AAiBnB,IAAM,sBAAsB;AAK5B,IAAM,sBAAsB,IAAI,KAAK;AAKrC,IAAM,yBAAyB;;;ACnE/B,SAAS,iBAAiB,SAAgC;AAE/D,MAAI,QAAQ,WAAW,GAAG,sBAAsB,GAAG,GAAG;AACpD,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,sBAAsB,IAAI,OAAO;AAC7C;AAoBO,SAAS,eAAe,SAA0B;AACvD,MAAI,CAAC,WAAW,QAAQ,SAAS,IAAI;AACnC,WAAO;AAAA,EACT;AACA,SAAO,QAAQ,WAAW,GAAG,mBAAmB,GAAG;AACrD;;;AC1BO,IAAM,0BAAN,MAA6D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlE,YACmB,QACA,SAAwC,CAAC,GAC1D;AAFiB;AACA;AAVnB,SAAS,SAAS;AAAA,EAWf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcH,MAAM,qBACJ,aACA,qBAC0D;AAE1D,UAAM,UAAU,iBAAiB,oBAAoB,OAAO;AAG5D,QAAI,CAAC,oBAAoB,OAAO;AAC9B,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,QAAI,CAAC,oBAAoB,QAAQ;AAC/B,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AAGA,QAAI,CAAC,eAAe,oBAAoB,KAAK,GAAG;AAC9C,YAAM,IAAI,MAAM,8BAA8B,oBAAoB,KAAK,EAAE;AAAA,IAC3E;AACA,QAAI,CAAC,eAAe,KAAK,OAAO,OAAO,GAAG;AACxC,YAAM,IAAI,MAAM,2BAA2B,KAAK,OAAO,OAAO,EAAE;AAAA,IAClE;AAEA,UAAM,YAAY,oBAAoB;AACtC,UAAM,SAAS,oBAAoB;AAGnC,UAAM,QACH,oBAAoB,OAAO,SAAoB,KAAK,OAAO,SAAS;AAGvE,UAAM,SAAS,MAAM,KAAK,OAAO,WAAW,SAAS,WAAW,QAAQ,KAAK;AAG7E,UAAM,UAAoC;AAAA,MACxC;AAAA,MACA,MAAM,KAAK,OAAO;AAAA,MAClB,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/exact-direct/client/index.ts","../../../../src/constants.ts","../../../../src/utils.ts","../../../../src/exact-direct/client/scheme.ts"],"sourcesContent":["/**\n * Cosmos Exact-Direct Client Exports\n */\n\nexport { ExactDirectCosmosClient, type ExactDirectCosmosClientConfig } from \"./scheme.js\";\n","/**\n * Cosmos Network Constants\n *\n * This module provides constants for Cosmos blockchain integration including:\n * - CAIP-2 network identifiers (Noble chain)\n * - RPC and REST endpoints\n * - Bech32 prefix configuration\n * - USDC denomination and gas parameters\n */\n\n/**\n * CAIP-2 Network Identifiers for Cosmos (Noble)\n */\nexport const NOBLE_MAINNET_CAIP2 = \"cosmos:noble-1\";\nexport const NOBLE_TESTNET_CAIP2 = \"cosmos:grand-1\";\n\n/**\n * Supported Cosmos networks\n */\nexport const COSMOS_NETWORKS = [NOBLE_MAINNET_CAIP2, NOBLE_TESTNET_CAIP2] as const;\n\nexport type CosmosNetwork = (typeof COSMOS_NETWORKS)[number];\n\n/**\n * Default RPC endpoints\n */\nexport const NOBLE_MAINNET_RPC = \"https://noble-rpc.polkachu.com\";\nexport const NOBLE_TESTNET_RPC = \"https://rpc.testnet.noble.strange.love\";\n\n/**\n * Default REST endpoints\n */\nexport const NOBLE_MAINNET_REST = \"https://noble-api.polkachu.com\";\nexport const NOBLE_TESTNET_REST = \"https://api.testnet.noble.strange.love\";\n\n/**\n * Network RPC endpoint mapping\n */\nexport const NETWORK_RPC_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_RPC,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_RPC,\n};\n\n/**\n * Network REST endpoint mapping\n */\nexport const NETWORK_REST_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_REST,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_REST,\n};\n\n/**\n * Bech32 prefix for Noble addresses\n */\nexport const NOBLE_BECH32_PREFIX = \"noble\";\n\n/**\n * USDC denomination on Noble\n * uusdc = micro-USDC (1 USDC = 1,000,000 uusdc)\n */\nexport const USDC_DENOM = \"uusdc\";\n\n/**\n * Default gas parameters\n */\nexport const DEFAULT_GAS_LIMIT = 200000;\nexport const DEFAULT_GAS_PRICE = \"0.025uusdc\";\nexport const DEFAULT_FEE_AMOUNT = \"5000\"; // 0.005 USDC\n\n/**\n * Cosmos message type for bank send\n */\nexport const MSG_TYPE_SEND = \"/cosmos.bank.v1beta1.MsgSend\";\n\n/**\n * Scheme identifier for exact-direct payments\n */\nexport const SCHEME_EXACT_DIRECT = \"exact-direct\";\n\n/**\n * Maximum transaction age to accept (in milliseconds)\n */\nexport const MAX_TRANSACTION_AGE = 5 * 60 * 1000; // 5 minutes\n\n/**\n * CAIP-2 namespace for Cosmos\n */\nexport const COSMOS_CAIP2_NAMESPACE = \"cosmos\";\n","/**\n * Cosmos Utility Functions\n *\n * Helper functions for Cosmos address validation, network normalization,\n * and amount conversion.\n */\n\nimport {\n COSMOS_CAIP2_NAMESPACE,\n NOBLE_BECH32_PREFIX,\n NETWORK_RPC_ENDPOINTS,\n NETWORK_REST_ENDPOINTS,\n type CosmosNetwork,\n} from \"./constants.js\";\n\n/**\n * Normalize a network identifier to CAIP-2 format\n * @param network - Network identifier (e.g., \"noble-1\", \"cosmos:noble-1\")\n * @returns CAIP-2 formatted network identifier\n */\nexport function normalizeNetwork(network: string): CosmosNetwork {\n // Already in CAIP-2 format\n if (network.startsWith(`${COSMOS_CAIP2_NAMESPACE}:`)) {\n return network as CosmosNetwork;\n }\n // Convert shorthand to CAIP-2\n return `${COSMOS_CAIP2_NAMESPACE}:${network}` as CosmosNetwork;\n}\n\n/**\n * Extract network ID from CAIP-2 identifier\n * @param network - CAIP-2 network identifier\n * @returns Network ID (e.g., \"noble-1\")\n */\nexport function extractNetworkId(network: string): string {\n if (network.includes(\":\")) {\n return network.split(\":\")[1];\n }\n return network;\n}\n\n/**\n * Validate a Cosmos bech32 address with Noble prefix\n * Checks that the address starts with the \"noble\" prefix followed by \"1\"\n * @param address - Address to validate\n * @returns Whether the address is valid\n */\nexport function isValidAddress(address: string): boolean {\n if (!address || address.length < 10) {\n return false;\n }\n return address.startsWith(`${NOBLE_BECH32_PREFIX}1`);\n}\n\n/**\n * Get RPC endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns RPC endpoint URL\n */\nexport function getRpcEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_RPC_ENDPOINTS[normalizedNetwork] || NETWORK_RPC_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Get REST endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns REST endpoint URL\n */\nexport function getRestEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_REST_ENDPOINTS[normalizedNetwork] || NETWORK_REST_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Convert decimal amount to token units (atomic units)\n * @param decimalAmount - Amount with decimals (e.g., \"1.50\")\n * @param decimals - Token decimals\n * @returns Amount in smallest units\n */\nexport function toAtomicUnits(decimalAmount: string | number, decimals: number): bigint {\n const amount = typeof decimalAmount === \"string\" ? parseFloat(decimalAmount) : decimalAmount;\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const multiplier = 10 ** decimals;\n return BigInt(Math.floor(amount * multiplier));\n}\n\n/**\n * Format amount for display (with decimals)\n * @param amount - Amount in smallest units\n * @param decimals - Number of decimal places\n * @returns Formatted amount string\n */\nexport function formatAmount(amount: bigint, decimals: number): string {\n const divisor = BigInt(10 ** decimals);\n const whole = amount / divisor;\n const remainder = amount % divisor;\n const decimal = remainder.toString().padStart(decimals, \"0\").slice(0, 2);\n return `${whole}.${decimal}`;\n}\n\n/**\n * Get the list of supported networks\n * @returns Array of CAIP-2 network identifiers\n */\nexport function getSupportedNetworks(): string[] {\n return Object.keys(NETWORK_RPC_ENDPOINTS);\n}\n","/**\n * Cosmos Client Scheme Implementation - Exact Direct\n *\n * Creates payment payloads for Cosmos MsgSend transfers using the exact-direct scheme.\n * In this scheme, the client executes the bank send directly and provides\n * the transaction hash as proof of payment.\n */\n\nimport type { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport type { ClientCosmosSigner, ExactDirectCosmosPayload } from \"../../types.js\";\nimport { SCHEME_EXACT_DIRECT, USDC_DENOM } from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\n\n/**\n * Configuration for ExactDirectCosmosClient\n */\nexport interface ExactDirectCosmosClientConfig {\n /** Override the default denomination */\n denom?: string;\n}\n\n/**\n * Cosmos client implementation for the Exact-Direct payment scheme.\n *\n * Executes a Cosmos MsgSend and returns the transaction hash as proof.\n */\nexport class ExactDirectCosmosClient implements SchemeNetworkClient {\n readonly scheme = SCHEME_EXACT_DIRECT;\n\n /**\n * Creates a new ExactDirectCosmosClient instance.\n *\n * @param signer - The Cosmos signer for client operations\n * @param config - Optional configuration overrides\n */\n constructor(\n private readonly signer: ClientCosmosSigner,\n private readonly config: ExactDirectCosmosClientConfig = {},\n ) {}\n\n /**\n * Creates a payment payload by executing the transfer.\n *\n * Unlike other schemes where the client creates a signed message for\n * the facilitator to execute, the exact-direct scheme has the client\n * execute the transfer directly. The transaction hash is then used\n * as proof of payment.\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload with transaction hash\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Normalize and validate network\n const network = normalizeNetwork(paymentRequirements.network);\n\n // Validate required fields\n if (!paymentRequirements.payTo) {\n throw new Error(\"PayTo address is required\");\n }\n if (!paymentRequirements.amount) {\n throw new Error(\"Amount is required\");\n }\n\n // Validate addresses\n if (!isValidAddress(paymentRequirements.payTo)) {\n throw new Error(`Invalid recipient address: ${paymentRequirements.payTo}`);\n }\n if (!isValidAddress(this.signer.address)) {\n throw new Error(`Invalid sender address: ${this.signer.address}`);\n }\n\n const recipient = paymentRequirements.payTo;\n const amount = paymentRequirements.amount;\n\n // Determine denomination from extra field, config, or default\n const denom = (paymentRequirements.extra?.denom as string) || this.config.denom || USDC_DENOM;\n\n // Execute the transfer\n const txHash = await this.signer.sendTokens(network, recipient, amount, denom);\n\n // Build the payload\n const payload: ExactDirectCosmosPayload = {\n txHash,\n from: this.signer.address,\n to: recipient,\n amount: amount,\n denom,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACaO,IAAM,sBAAsB;AAC5B,IAAM,sBAAsB;AAY5B,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAK1B,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAK3B,IAAM,wBAAgD;AAAA,EAC3D,CAAC,mBAAmB,GAAG;AAAA,EACvB,CAAC,mBAAmB,GAAG;AACzB;AAKO,IAAM,yBAAiD;AAAA,EAC5D,CAAC,mBAAmB,GAAG;AAAA,EACvB,CAAC,mBAAmB,GAAG;AACzB;AAKO,IAAM,sBAAsB;AAM5B,IAAM,aAAa;AAiBnB,IAAM,sBAAsB;AAK5B,IAAM,sBAAsB,IAAI,KAAK;AAKrC,IAAM,yBAAyB;;;ACnE/B,SAAS,iBAAiB,SAAgC;AAE/D,MAAI,QAAQ,WAAW,GAAG,sBAAsB,GAAG,GAAG;AACpD,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,sBAAsB,IAAI,OAAO;AAC7C;AAoBO,SAAS,eAAe,SAA0B;AACvD,MAAI,CAAC,WAAW,QAAQ,SAAS,IAAI;AACnC,WAAO;AAAA,EACT;AACA,SAAO,QAAQ,WAAW,GAAG,mBAAmB,GAAG;AACrD;;;AC1BO,IAAM,0BAAN,MAA6D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlE,YACmB,QACA,SAAwC,CAAC,GAC1D;AAFiB;AACA;AAVnB,SAAS,SAAS;AAAA,EAWf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcH,MAAM,qBACJ,aACA,qBAC0D;AAE1D,UAAM,UAAU,iBAAiB,oBAAoB,OAAO;AAG5D,QAAI,CAAC,oBAAoB,OAAO;AAC9B,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,QAAI,CAAC,oBAAoB,QAAQ;AAC/B,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AAGA,QAAI,CAAC,eAAe,oBAAoB,KAAK,GAAG;AAC9C,YAAM,IAAI,MAAM,8BAA8B,oBAAoB,KAAK,EAAE;AAAA,IAC3E;AACA,QAAI,CAAC,eAAe,KAAK,OAAO,OAAO,GAAG;AACxC,YAAM,IAAI,MAAM,2BAA2B,KAAK,OAAO,OAAO,EAAE;AAAA,IAClE;AAEA,UAAM,YAAY,oBAAoB;AACtC,UAAM,SAAS,oBAAoB;AAGnC,UAAM,QAAS,oBAAoB,OAAO,SAAoB,KAAK,OAAO,SAAS;AAGnF,UAAM,SAAS,MAAM,KAAK,OAAO,WAAW,SAAS,WAAW,QAAQ,KAAK;AAG7E,UAAM,UAAoC;AAAA,MACxC;AAAA,MACA,MAAM,KAAK,OAAO;AAAA,MAClB,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -1,5 +1,5 @@
1
1
  import { SchemeNetworkFacilitator, Network, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse } from '@t402/core/types';
2
- import { F as FacilitatorCosmosSigner } from '../../types-CgseoctH.js';
2
+ import { F as FacilitatorCosmosSigner } from '../../types-27CIV52j.js';
3
3
 
4
4
  /**
5
5
  * Cosmos Facilitator Scheme Implementation - Exact Direct
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/exact-direct/facilitator/index.ts","../../../../src/constants.ts","../../../../src/utils.ts","../../../../src/tokens.ts","../../../../src/exact-direct/facilitator/scheme.ts"],"sourcesContent":["/**\n * Cosmos Exact-Direct Facilitator Exports\n */\n\nexport { ExactDirectCosmosFacilitator, type ExactDirectCosmosFacilitatorConfig } from \"./scheme.js\";\n","/**\n * Cosmos Network Constants\n *\n * This module provides constants for Cosmos blockchain integration including:\n * - CAIP-2 network identifiers (Noble chain)\n * - RPC and REST endpoints\n * - Bech32 prefix configuration\n * - USDC denomination and gas parameters\n */\n\n/**\n * CAIP-2 Network Identifiers for Cosmos (Noble)\n */\nexport const NOBLE_MAINNET_CAIP2 = \"cosmos:noble-1\";\nexport const NOBLE_TESTNET_CAIP2 = \"cosmos:grand-1\";\n\n/**\n * Supported Cosmos networks\n */\nexport const COSMOS_NETWORKS = [NOBLE_MAINNET_CAIP2, NOBLE_TESTNET_CAIP2] as const;\n\nexport type CosmosNetwork = (typeof COSMOS_NETWORKS)[number];\n\n/**\n * Default RPC endpoints\n */\nexport const NOBLE_MAINNET_RPC = \"https://noble-rpc.polkachu.com\";\nexport const NOBLE_TESTNET_RPC = \"https://rpc.testnet.noble.strange.love\";\n\n/**\n * Default REST endpoints\n */\nexport const NOBLE_MAINNET_REST = \"https://noble-api.polkachu.com\";\nexport const NOBLE_TESTNET_REST = \"https://api.testnet.noble.strange.love\";\n\n/**\n * Network RPC endpoint mapping\n */\nexport const NETWORK_RPC_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_RPC,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_RPC,\n};\n\n/**\n * Network REST endpoint mapping\n */\nexport const NETWORK_REST_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_REST,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_REST,\n};\n\n/**\n * Bech32 prefix for Noble addresses\n */\nexport const NOBLE_BECH32_PREFIX = \"noble\";\n\n/**\n * USDC denomination on Noble\n * uusdc = micro-USDC (1 USDC = 1,000,000 uusdc)\n */\nexport const USDC_DENOM = \"uusdc\";\n\n/**\n * Default gas parameters\n */\nexport const DEFAULT_GAS_LIMIT = 200000;\nexport const DEFAULT_GAS_PRICE = \"0.025uusdc\";\nexport const DEFAULT_FEE_AMOUNT = \"5000\"; // 0.005 USDC\n\n/**\n * Cosmos message type for bank send\n */\nexport const MSG_TYPE_SEND = \"/cosmos.bank.v1beta1.MsgSend\";\n\n/**\n * Scheme identifier for exact-direct payments\n */\nexport const SCHEME_EXACT_DIRECT = \"exact-direct\";\n\n/**\n * Maximum transaction age to accept (in milliseconds)\n */\nexport const MAX_TRANSACTION_AGE = 5 * 60 * 1000; // 5 minutes\n\n/**\n * CAIP-2 namespace for Cosmos\n */\nexport const COSMOS_CAIP2_NAMESPACE = \"cosmos\";\n","/**\n * Cosmos Utility Functions\n *\n * Helper functions for Cosmos address validation, network normalization,\n * and amount conversion.\n */\n\nimport {\n COSMOS_CAIP2_NAMESPACE,\n NOBLE_BECH32_PREFIX,\n NETWORK_RPC_ENDPOINTS,\n NETWORK_REST_ENDPOINTS,\n type CosmosNetwork,\n} from \"./constants.js\";\n\n/**\n * Normalize a network identifier to CAIP-2 format\n * @param network - Network identifier (e.g., \"noble-1\", \"cosmos:noble-1\")\n * @returns CAIP-2 formatted network identifier\n */\nexport function normalizeNetwork(network: string): CosmosNetwork {\n // Already in CAIP-2 format\n if (network.startsWith(`${COSMOS_CAIP2_NAMESPACE}:`)) {\n return network as CosmosNetwork;\n }\n // Convert shorthand to CAIP-2\n return `${COSMOS_CAIP2_NAMESPACE}:${network}` as CosmosNetwork;\n}\n\n/**\n * Extract network ID from CAIP-2 identifier\n * @param network - CAIP-2 network identifier\n * @returns Network ID (e.g., \"noble-1\")\n */\nexport function extractNetworkId(network: string): string {\n if (network.includes(\":\")) {\n return network.split(\":\")[1];\n }\n return network;\n}\n\n/**\n * Validate a Cosmos bech32 address with Noble prefix\n * Checks that the address starts with the \"noble\" prefix followed by \"1\"\n * @param address - Address to validate\n * @returns Whether the address is valid\n */\nexport function isValidAddress(address: string): boolean {\n if (!address || address.length < 10) {\n return false;\n }\n return address.startsWith(`${NOBLE_BECH32_PREFIX}1`);\n}\n\n/**\n * Get RPC endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns RPC endpoint URL\n */\nexport function getRpcEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_RPC_ENDPOINTS[normalizedNetwork] || NETWORK_RPC_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Get REST endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns REST endpoint URL\n */\nexport function getRestEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_REST_ENDPOINTS[normalizedNetwork] || NETWORK_REST_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Convert decimal amount to token units (atomic units)\n * @param decimalAmount - Amount with decimals (e.g., \"1.50\")\n * @param decimals - Token decimals\n * @returns Amount in smallest units\n */\nexport function toAtomicUnits(decimalAmount: string | number, decimals: number): bigint {\n const amount = typeof decimalAmount === \"string\" ? parseFloat(decimalAmount) : decimalAmount;\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const multiplier = 10 ** decimals;\n return BigInt(Math.floor(amount * multiplier));\n}\n\n/**\n * Format amount for display (with decimals)\n * @param amount - Amount in smallest units\n * @param decimals - Number of decimal places\n * @returns Formatted amount string\n */\nexport function formatAmount(amount: bigint, decimals: number): string {\n const divisor = BigInt(10 ** decimals);\n const whole = amount / divisor;\n const remainder = amount % divisor;\n const decimal = remainder.toString().padStart(decimals, \"0\").slice(0, 2);\n return `${whole}.${decimal}`;\n}\n\n/**\n * Get the list of supported networks\n * @returns Array of CAIP-2 network identifiers\n */\nexport function getSupportedNetworks(): string[] {\n return Object.keys(NETWORK_RPC_ENDPOINTS);\n}\n","/**\n * Cosmos Token Registry\n *\n * Defines supported tokens for each Cosmos network (currently Noble USDC).\n */\n\nimport { NOBLE_MAINNET_CAIP2, NOBLE_TESTNET_CAIP2, USDC_DENOM } from \"./constants.js\";\nimport type { TokenConfig } from \"./types.js\";\n\n/**\n * Token registry by network\n */\nexport const TOKEN_REGISTRY: Record<string, TokenConfig[]> = {\n [NOBLE_MAINNET_CAIP2]: [\n {\n denom: USDC_DENOM,\n symbol: \"USDC\",\n name: \"USD Coin\",\n decimals: 6,\n priority: 1,\n },\n ],\n [NOBLE_TESTNET_CAIP2]: [\n {\n denom: USDC_DENOM,\n symbol: \"USDC\",\n name: \"USD Coin (Testnet)\",\n decimals: 6,\n priority: 1,\n },\n ],\n};\n\n/**\n * Get token configuration by symbol\n * @param network - CAIP-2 network identifier\n * @param symbol - Token symbol (e.g., \"USDC\")\n * @returns Token configuration or undefined\n */\nexport function getTokenConfig(network: string, symbol: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return undefined;\n return tokens.find((t) => t.symbol.toUpperCase() === symbol.toUpperCase());\n}\n\n/**\n * Get token configuration by denomination\n * @param network - CAIP-2 network identifier\n * @param denom - Token denomination (e.g., \"uusdc\")\n * @returns Token configuration or undefined\n */\nexport function getTokenByDenom(network: string, denom: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return undefined;\n return tokens.find((t) => t.denom === denom);\n}\n\n/**\n * Get the default token for a network\n * Returns the token with highest priority (lowest priority number)\n * @param network - CAIP-2 network identifier\n * @returns Default token configuration or undefined\n */\nexport function getDefaultToken(network: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens || tokens.length === 0) return undefined;\n return [...tokens].sort((a, b) => a.priority - b.priority)[0];\n}\n\n/**\n * Get all tokens for a network\n * @param network - CAIP-2 network identifier\n * @returns Array of token configurations\n */\nexport function getNetworkTokens(network: string): TokenConfig[] {\n return TOKEN_REGISTRY[network] || [];\n}\n\n/**\n * Check if a network is supported\n * @param network - CAIP-2 network identifier\n */\nexport function isNetworkSupported(network: string): boolean {\n return network in TOKEN_REGISTRY;\n}\n","/**\n * Cosmos Facilitator Scheme Implementation - Exact Direct\n *\n * Verifies and settles Cosmos (Noble USDC) payments using the exact-direct scheme.\n * The facilitator verifies that the client's transaction was successful\n * and matches the payment requirements.\n */\n\nimport type {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport type { FacilitatorCosmosSigner, ExactDirectCosmosPayload, MsgSend } from \"../../types.js\";\nimport { SCHEME_EXACT_DIRECT, COSMOS_CAIP2_NAMESPACE, MAX_TRANSACTION_AGE, MSG_TYPE_SEND } from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\nimport { getDefaultToken } from \"../../tokens.js\";\n\n/**\n * Configuration for ExactDirectCosmosFacilitator\n */\nexport interface ExactDirectCosmosFacilitatorConfig {\n /** Maximum age of a transaction to accept (in milliseconds) */\n maxTransactionAge?: number;\n /** Duration to cache used transaction hashes (in milliseconds) */\n usedTxCacheDuration?: number;\n}\n\n/**\n * Cosmos facilitator implementation for the Exact-Direct payment scheme.\n * Verifies transaction proofs and confirms payments.\n */\nexport class ExactDirectCosmosFacilitator implements SchemeNetworkFacilitator {\n readonly scheme = SCHEME_EXACT_DIRECT;\n readonly caipFamily = `${COSMOS_CAIP2_NAMESPACE}:*`;\n\n private readonly config: Required<ExactDirectCosmosFacilitatorConfig>;\n private usedTxs: Map<string, number> = new Map();\n\n constructor(\n private readonly signer: FacilitatorCosmosSigner,\n config?: ExactDirectCosmosFacilitatorConfig,\n ) {\n this.config = {\n maxTransactionAge: config?.maxTransactionAge ?? MAX_TRANSACTION_AGE,\n usedTxCacheDuration: config?.usedTxCacheDuration ?? 24 * 60 * 60 * 1000, // 24 hours\n };\n\n // Start cleanup interval\n this.startCleanupInterval();\n }\n\n /**\n * Get extra data for a supported kind\n */\n getExtra(network: Network): Record<string, unknown> | undefined {\n const token = getDefaultToken(network);\n if (!token) {\n return undefined;\n }\n return {\n assetSymbol: token.symbol,\n assetDecimals: token.decimals,\n assetDenom: token.denom,\n };\n }\n\n /**\n * Get signer addresses for a network\n */\n getSigners(network: Network): string[] {\n return this.signer.getAddresses(network);\n }\n\n /**\n * Verify a payment payload\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const network = normalizeNetwork(requirements.network);\n\n // Validate scheme\n if (payload.accepted.scheme !== SCHEME_EXACT_DIRECT) {\n return {\n isValid: false,\n invalidReason: \"invalid_scheme\",\n };\n }\n\n // Validate network\n if (normalizeNetwork(payload.accepted.network) !== network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n };\n }\n\n // Parse payload\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n if (!cosmosPayload.txHash) {\n return {\n isValid: false,\n invalidReason: \"missing_tx_hash\",\n };\n }\n if (!cosmosPayload.from || !isValidAddress(cosmosPayload.from)) {\n return {\n isValid: false,\n invalidReason: \"invalid_from_address\",\n };\n }\n\n // Check for replay attack\n if (this.isTxUsed(cosmosPayload.txHash)) {\n return {\n isValid: false,\n invalidReason: \"transaction_already_used\",\n payer: cosmosPayload.from,\n };\n }\n\n try {\n // Query the transaction\n const tx = await this.signer.queryTransaction(network, cosmosPayload.txHash);\n\n // Check transaction succeeded (code 0 = success)\n if (tx.code !== 0) {\n return {\n isValid: false,\n invalidReason: \"transaction_failed\",\n payer: cosmosPayload.from,\n };\n }\n\n // Find the MsgSend in the transaction messages\n const msgSend = this.findMsgSend(tx.tx.body.messages);\n if (!msgSend) {\n return {\n isValid: false,\n invalidReason: \"no_msg_send_found\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify recipient\n if (msgSend.toAddress !== requirements.payTo) {\n return {\n isValid: false,\n invalidReason: \"wrong_recipient\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify sender matches payload\n if (msgSend.fromAddress !== cosmosPayload.from) {\n return {\n isValid: false,\n invalidReason: \"sender_mismatch\",\n payer: cosmosPayload.from,\n };\n }\n\n // Determine expected denom\n const expectedDenom = (requirements.extra?.denom as string) || requirements.asset;\n\n // Verify amount and denomination\n const coin = this.getAmountByDenom(msgSend, expectedDenom);\n if (!coin) {\n return {\n isValid: false,\n invalidReason: \"wrong_denomination\",\n payer: cosmosPayload.from,\n };\n }\n\n const txAmount = BigInt(coin.amount);\n const requiredAmount = BigInt(requirements.amount);\n if (txAmount < requiredAmount) {\n return {\n isValid: false,\n invalidReason: \"insufficient_amount\",\n payer: cosmosPayload.from,\n };\n }\n\n // Mark transaction as used\n this.markTxUsed(cosmosPayload.txHash);\n\n return {\n isValid: true,\n payer: cosmosPayload.from,\n };\n } catch {\n return {\n isValid: false,\n invalidReason: \"transaction_not_found\",\n payer: cosmosPayload.from,\n };\n }\n }\n\n /**\n * Settle a payment - for exact-direct, the transfer is already complete\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n // Verify first\n const verifyResult = await this.verify(payload, requirements);\n if (!verifyResult.isValid) {\n return {\n success: false,\n errorReason: verifyResult.invalidReason || \"verification_failed\",\n payer: verifyResult.payer,\n transaction: \"\",\n network: normalizeNetwork(requirements.network),\n };\n }\n\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n\n // For exact-direct, settlement is already complete\n return {\n success: true,\n transaction: cosmosPayload.txHash,\n network: normalizeNetwork(requirements.network),\n payer: cosmosPayload.from,\n };\n }\n\n /**\n * Find a MsgSend in transaction messages\n */\n private findMsgSend(messages: MsgSend[]): MsgSend | null {\n for (const msg of messages) {\n if (msg[\"@type\"] === MSG_TYPE_SEND || (!msg[\"@type\"] && msg.fromAddress && msg.toAddress)) {\n return msg;\n }\n }\n return null;\n }\n\n /**\n * Get a specific coin amount from a MsgSend by denomination\n */\n private getAmountByDenom(msg: MsgSend, denom: string): { denom: string; amount: string } | null {\n for (const coin of msg.amount) {\n if (coin.denom === denom) {\n return coin;\n }\n }\n return null;\n }\n\n /**\n * Check if a transaction has been used\n */\n private isTxUsed(txHash: string): boolean {\n return this.usedTxs.has(txHash);\n }\n\n /**\n * Mark a transaction as used\n */\n private markTxUsed(txHash: string): void {\n this.usedTxs.set(txHash, Date.now());\n }\n\n /**\n * Start the cleanup interval for used transactions\n */\n private startCleanupInterval(): void {\n setInterval(\n () => {\n const cutoff = Date.now() - this.config.usedTxCacheDuration;\n for (const [txHash, usedAt] of this.usedTxs.entries()) {\n if (usedAt < cutoff) {\n this.usedTxs.delete(txHash);\n }\n }\n },\n 60 * 60 * 1000,\n ); // Cleanup every hour\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/exact-direct/facilitator/index.ts","../../../../src/constants.ts","../../../../src/utils.ts","../../../../src/tokens.ts","../../../../src/exact-direct/facilitator/scheme.ts"],"sourcesContent":["/**\n * Cosmos Exact-Direct Facilitator Exports\n */\n\nexport { ExactDirectCosmosFacilitator, type ExactDirectCosmosFacilitatorConfig } from \"./scheme.js\";\n","/**\n * Cosmos Network Constants\n *\n * This module provides constants for Cosmos blockchain integration including:\n * - CAIP-2 network identifiers (Noble chain)\n * - RPC and REST endpoints\n * - Bech32 prefix configuration\n * - USDC denomination and gas parameters\n */\n\n/**\n * CAIP-2 Network Identifiers for Cosmos (Noble)\n */\nexport const NOBLE_MAINNET_CAIP2 = \"cosmos:noble-1\";\nexport const NOBLE_TESTNET_CAIP2 = \"cosmos:grand-1\";\n\n/**\n * Supported Cosmos networks\n */\nexport const COSMOS_NETWORKS = [NOBLE_MAINNET_CAIP2, NOBLE_TESTNET_CAIP2] as const;\n\nexport type CosmosNetwork = (typeof COSMOS_NETWORKS)[number];\n\n/**\n * Default RPC endpoints\n */\nexport const NOBLE_MAINNET_RPC = \"https://noble-rpc.polkachu.com\";\nexport const NOBLE_TESTNET_RPC = \"https://rpc.testnet.noble.strange.love\";\n\n/**\n * Default REST endpoints\n */\nexport const NOBLE_MAINNET_REST = \"https://noble-api.polkachu.com\";\nexport const NOBLE_TESTNET_REST = \"https://api.testnet.noble.strange.love\";\n\n/**\n * Network RPC endpoint mapping\n */\nexport const NETWORK_RPC_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_RPC,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_RPC,\n};\n\n/**\n * Network REST endpoint mapping\n */\nexport const NETWORK_REST_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_REST,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_REST,\n};\n\n/**\n * Bech32 prefix for Noble addresses\n */\nexport const NOBLE_BECH32_PREFIX = \"noble\";\n\n/**\n * USDC denomination on Noble\n * uusdc = micro-USDC (1 USDC = 1,000,000 uusdc)\n */\nexport const USDC_DENOM = \"uusdc\";\n\n/**\n * Default gas parameters\n */\nexport const DEFAULT_GAS_LIMIT = 200000;\nexport const DEFAULT_GAS_PRICE = \"0.025uusdc\";\nexport const DEFAULT_FEE_AMOUNT = \"5000\"; // 0.005 USDC\n\n/**\n * Cosmos message type for bank send\n */\nexport const MSG_TYPE_SEND = \"/cosmos.bank.v1beta1.MsgSend\";\n\n/**\n * Scheme identifier for exact-direct payments\n */\nexport const SCHEME_EXACT_DIRECT = \"exact-direct\";\n\n/**\n * Maximum transaction age to accept (in milliseconds)\n */\nexport const MAX_TRANSACTION_AGE = 5 * 60 * 1000; // 5 minutes\n\n/**\n * CAIP-2 namespace for Cosmos\n */\nexport const COSMOS_CAIP2_NAMESPACE = \"cosmos\";\n","/**\n * Cosmos Utility Functions\n *\n * Helper functions for Cosmos address validation, network normalization,\n * and amount conversion.\n */\n\nimport {\n COSMOS_CAIP2_NAMESPACE,\n NOBLE_BECH32_PREFIX,\n NETWORK_RPC_ENDPOINTS,\n NETWORK_REST_ENDPOINTS,\n type CosmosNetwork,\n} from \"./constants.js\";\n\n/**\n * Normalize a network identifier to CAIP-2 format\n * @param network - Network identifier (e.g., \"noble-1\", \"cosmos:noble-1\")\n * @returns CAIP-2 formatted network identifier\n */\nexport function normalizeNetwork(network: string): CosmosNetwork {\n // Already in CAIP-2 format\n if (network.startsWith(`${COSMOS_CAIP2_NAMESPACE}:`)) {\n return network as CosmosNetwork;\n }\n // Convert shorthand to CAIP-2\n return `${COSMOS_CAIP2_NAMESPACE}:${network}` as CosmosNetwork;\n}\n\n/**\n * Extract network ID from CAIP-2 identifier\n * @param network - CAIP-2 network identifier\n * @returns Network ID (e.g., \"noble-1\")\n */\nexport function extractNetworkId(network: string): string {\n if (network.includes(\":\")) {\n return network.split(\":\")[1];\n }\n return network;\n}\n\n/**\n * Validate a Cosmos bech32 address with Noble prefix\n * Checks that the address starts with the \"noble\" prefix followed by \"1\"\n * @param address - Address to validate\n * @returns Whether the address is valid\n */\nexport function isValidAddress(address: string): boolean {\n if (!address || address.length < 10) {\n return false;\n }\n return address.startsWith(`${NOBLE_BECH32_PREFIX}1`);\n}\n\n/**\n * Get RPC endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns RPC endpoint URL\n */\nexport function getRpcEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_RPC_ENDPOINTS[normalizedNetwork] || NETWORK_RPC_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Get REST endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns REST endpoint URL\n */\nexport function getRestEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_REST_ENDPOINTS[normalizedNetwork] || NETWORK_REST_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Convert decimal amount to token units (atomic units)\n * @param decimalAmount - Amount with decimals (e.g., \"1.50\")\n * @param decimals - Token decimals\n * @returns Amount in smallest units\n */\nexport function toAtomicUnits(decimalAmount: string | number, decimals: number): bigint {\n const amount = typeof decimalAmount === \"string\" ? parseFloat(decimalAmount) : decimalAmount;\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const multiplier = 10 ** decimals;\n return BigInt(Math.floor(amount * multiplier));\n}\n\n/**\n * Format amount for display (with decimals)\n * @param amount - Amount in smallest units\n * @param decimals - Number of decimal places\n * @returns Formatted amount string\n */\nexport function formatAmount(amount: bigint, decimals: number): string {\n const divisor = BigInt(10 ** decimals);\n const whole = amount / divisor;\n const remainder = amount % divisor;\n const decimal = remainder.toString().padStart(decimals, \"0\").slice(0, 2);\n return `${whole}.${decimal}`;\n}\n\n/**\n * Get the list of supported networks\n * @returns Array of CAIP-2 network identifiers\n */\nexport function getSupportedNetworks(): string[] {\n return Object.keys(NETWORK_RPC_ENDPOINTS);\n}\n","/**\n * Cosmos Token Registry\n *\n * Defines supported tokens for each Cosmos network (currently Noble USDC).\n */\n\nimport { NOBLE_MAINNET_CAIP2, NOBLE_TESTNET_CAIP2, USDC_DENOM } from \"./constants.js\";\nimport type { TokenConfig } from \"./types.js\";\n\n/**\n * Token registry by network\n */\nexport const TOKEN_REGISTRY: Record<string, TokenConfig[]> = {\n [NOBLE_MAINNET_CAIP2]: [\n {\n denom: USDC_DENOM,\n symbol: \"USDC\",\n name: \"USD Coin\",\n decimals: 6,\n priority: 1,\n },\n ],\n [NOBLE_TESTNET_CAIP2]: [\n {\n denom: USDC_DENOM,\n symbol: \"USDC\",\n name: \"USD Coin (Testnet)\",\n decimals: 6,\n priority: 1,\n },\n ],\n};\n\n/**\n * Get token configuration by symbol\n * @param network - CAIP-2 network identifier\n * @param symbol - Token symbol (e.g., \"USDC\")\n * @returns Token configuration or undefined\n */\nexport function getTokenConfig(network: string, symbol: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return undefined;\n return tokens.find((t) => t.symbol.toUpperCase() === symbol.toUpperCase());\n}\n\n/**\n * Get token configuration by denomination\n * @param network - CAIP-2 network identifier\n * @param denom - Token denomination (e.g., \"uusdc\")\n * @returns Token configuration or undefined\n */\nexport function getTokenByDenom(network: string, denom: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return undefined;\n return tokens.find((t) => t.denom === denom);\n}\n\n/**\n * Get the default token for a network\n * Returns the token with highest priority (lowest priority number)\n * @param network - CAIP-2 network identifier\n * @returns Default token configuration or undefined\n */\nexport function getDefaultToken(network: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens || tokens.length === 0) return undefined;\n return [...tokens].sort((a, b) => a.priority - b.priority)[0];\n}\n\n/**\n * Get all tokens for a network\n * @param network - CAIP-2 network identifier\n * @returns Array of token configurations\n */\nexport function getNetworkTokens(network: string): TokenConfig[] {\n return TOKEN_REGISTRY[network] || [];\n}\n\n/**\n * Check if a network is supported\n * @param network - CAIP-2 network identifier\n */\nexport function isNetworkSupported(network: string): boolean {\n return network in TOKEN_REGISTRY;\n}\n","/**\n * Cosmos Facilitator Scheme Implementation - Exact Direct\n *\n * Verifies and settles Cosmos (Noble USDC) payments using the exact-direct scheme.\n * The facilitator verifies that the client's transaction was successful\n * and matches the payment requirements.\n */\n\nimport type {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport type { FacilitatorCosmosSigner, ExactDirectCosmosPayload, MsgSend } from \"../../types.js\";\nimport {\n SCHEME_EXACT_DIRECT,\n COSMOS_CAIP2_NAMESPACE,\n MAX_TRANSACTION_AGE,\n MSG_TYPE_SEND,\n} from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\nimport { getDefaultToken } from \"../../tokens.js\";\n\n/**\n * Configuration for ExactDirectCosmosFacilitator\n */\nexport interface ExactDirectCosmosFacilitatorConfig {\n /** Maximum age of a transaction to accept (in milliseconds) */\n maxTransactionAge?: number;\n /** Duration to cache used transaction hashes (in milliseconds) */\n usedTxCacheDuration?: number;\n}\n\n/**\n * Cosmos facilitator implementation for the Exact-Direct payment scheme.\n * Verifies transaction proofs and confirms payments.\n */\nexport class ExactDirectCosmosFacilitator implements SchemeNetworkFacilitator {\n readonly scheme = SCHEME_EXACT_DIRECT;\n readonly caipFamily = `${COSMOS_CAIP2_NAMESPACE}:*`;\n\n private readonly config: Required<ExactDirectCosmosFacilitatorConfig>;\n private usedTxs: Map<string, number> = new Map();\n\n constructor(\n private readonly signer: FacilitatorCosmosSigner,\n config?: ExactDirectCosmosFacilitatorConfig,\n ) {\n this.config = {\n maxTransactionAge: config?.maxTransactionAge ?? MAX_TRANSACTION_AGE,\n usedTxCacheDuration: config?.usedTxCacheDuration ?? 24 * 60 * 60 * 1000, // 24 hours\n };\n\n // Start cleanup interval\n this.startCleanupInterval();\n }\n\n /**\n * Get extra data for a supported kind\n */\n getExtra(network: Network): Record<string, unknown> | undefined {\n const token = getDefaultToken(network);\n if (!token) {\n return undefined;\n }\n return {\n assetSymbol: token.symbol,\n assetDecimals: token.decimals,\n assetDenom: token.denom,\n };\n }\n\n /**\n * Get signer addresses for a network\n */\n getSigners(network: Network): string[] {\n return this.signer.getAddresses(network);\n }\n\n /**\n * Verify a payment payload\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const network = normalizeNetwork(requirements.network);\n\n // Validate scheme\n if (payload.accepted.scheme !== SCHEME_EXACT_DIRECT) {\n return {\n isValid: false,\n invalidReason: \"invalid_scheme\",\n };\n }\n\n // Validate network\n if (normalizeNetwork(payload.accepted.network) !== network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n };\n }\n\n // Parse payload\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n if (!cosmosPayload.txHash) {\n return {\n isValid: false,\n invalidReason: \"missing_tx_hash\",\n };\n }\n if (!cosmosPayload.from || !isValidAddress(cosmosPayload.from)) {\n return {\n isValid: false,\n invalidReason: \"invalid_from_address\",\n };\n }\n\n // Check for replay attack\n if (this.isTxUsed(cosmosPayload.txHash)) {\n return {\n isValid: false,\n invalidReason: \"transaction_already_used\",\n payer: cosmosPayload.from,\n };\n }\n\n try {\n // Query the transaction\n const tx = await this.signer.queryTransaction(network, cosmosPayload.txHash);\n\n // Check transaction succeeded (code 0 = success)\n if (tx.code !== 0) {\n return {\n isValid: false,\n invalidReason: \"transaction_failed\",\n payer: cosmosPayload.from,\n };\n }\n\n // Find the MsgSend in the transaction messages\n const msgSend = this.findMsgSend(tx.tx.body.messages);\n if (!msgSend) {\n return {\n isValid: false,\n invalidReason: \"no_msg_send_found\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify recipient\n if (msgSend.toAddress !== requirements.payTo) {\n return {\n isValid: false,\n invalidReason: \"wrong_recipient\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify sender matches payload\n if (msgSend.fromAddress !== cosmosPayload.from) {\n return {\n isValid: false,\n invalidReason: \"sender_mismatch\",\n payer: cosmosPayload.from,\n };\n }\n\n // Determine expected denom\n const expectedDenom = (requirements.extra?.denom as string) || requirements.asset;\n\n // Verify amount and denomination\n const coin = this.getAmountByDenom(msgSend, expectedDenom);\n if (!coin) {\n return {\n isValid: false,\n invalidReason: \"wrong_denomination\",\n payer: cosmosPayload.from,\n };\n }\n\n const txAmount = BigInt(coin.amount);\n const requiredAmount = BigInt(requirements.amount);\n if (txAmount < requiredAmount) {\n return {\n isValid: false,\n invalidReason: \"insufficient_amount\",\n payer: cosmosPayload.from,\n };\n }\n\n // Mark transaction as used\n this.markTxUsed(cosmosPayload.txHash);\n\n return {\n isValid: true,\n payer: cosmosPayload.from,\n };\n } catch {\n return {\n isValid: false,\n invalidReason: \"transaction_not_found\",\n payer: cosmosPayload.from,\n };\n }\n }\n\n /**\n * Settle a payment - for exact-direct, the transfer is already complete\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n // Verify first\n const verifyResult = await this.verify(payload, requirements);\n if (!verifyResult.isValid) {\n return {\n success: false,\n errorReason: verifyResult.invalidReason || \"verification_failed\",\n payer: verifyResult.payer,\n transaction: \"\",\n network: normalizeNetwork(requirements.network),\n };\n }\n\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n\n // For exact-direct, settlement is already complete\n return {\n success: true,\n transaction: cosmosPayload.txHash,\n network: normalizeNetwork(requirements.network),\n payer: cosmosPayload.from,\n };\n }\n\n /**\n * Find a MsgSend in transaction messages\n */\n private findMsgSend(messages: MsgSend[]): MsgSend | null {\n for (const msg of messages) {\n if (msg[\"@type\"] === MSG_TYPE_SEND || (!msg[\"@type\"] && msg.fromAddress && msg.toAddress)) {\n return msg;\n }\n }\n return null;\n }\n\n /**\n * Get a specific coin amount from a MsgSend by denomination\n */\n private getAmountByDenom(msg: MsgSend, denom: string): { denom: string; amount: string } | null {\n for (const coin of msg.amount) {\n if (coin.denom === denom) {\n return coin;\n }\n }\n return null;\n }\n\n /**\n * Check if a transaction has been used\n */\n private isTxUsed(txHash: string): boolean {\n return this.usedTxs.has(txHash);\n }\n\n /**\n * Mark a transaction as used\n */\n private markTxUsed(txHash: string): void {\n this.usedTxs.set(txHash, Date.now());\n }\n\n /**\n * Start the cleanup interval for used transactions\n */\n private startCleanupInterval(): void {\n setInterval(\n () => {\n const cutoff = Date.now() - this.config.usedTxCacheDuration;\n for (const [txHash, usedAt] of this.usedTxs.entries()) {\n if (usedAt < cutoff) {\n this.usedTxs.delete(txHash);\n }\n }\n },\n 60 * 60 * 1000,\n ); // Cleanup every hour\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,5 +1,5 @@
1
- import { T as TokenConfig } from './types-CgseoctH.js';
2
- export { d as ClientCosmosSigner, C as Coin, E as ExactDirectCosmosPayload, F as FacilitatorCosmosSigner, M as MsgSend, N as NetworkConfig, a as TransactionResult, c as TxBody, b as TxWrapper } from './types-CgseoctH.js';
1
+ import { T as TokenConfig } from './types-27CIV52j.js';
2
+ export { C as ClientCosmosSigner, a as Coin, E as ExactDirectCosmosPayload, F as FacilitatorCosmosSigner, M as MsgSend, N as NetworkConfig, b as TransactionResult, c as TxBody, d as TxWrapper } from './types-27CIV52j.js';
3
3
  export { ExactDirectCosmosClient, ExactDirectCosmosClientConfig } from './exact-direct/client/index.js';
4
4
  export { ExactDirectCosmosServer, ExactDirectCosmosServerConfig } from './exact-direct/server/index.js';
5
5
  export { ExactDirectCosmosFacilitator, ExactDirectCosmosFacilitatorConfig } from './exact-direct/facilitator/index.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/constants.ts","../../src/tokens.ts","../../src/utils.ts","../../src/exact-direct/client/scheme.ts","../../src/exact-direct/server/scheme.ts","../../src/exact-direct/facilitator/scheme.ts"],"sourcesContent":["/**\n * @t402/cosmos - Cosmos (Noble USDC) Implementation for T402\n *\n * This package provides Cosmos blockchain support for the T402 payment protocol.\n * It implements the exact-direct scheme using Noble's native USDC via MsgSend.\n *\n * @example\n * ```typescript\n * // Client usage\n * import { ExactDirectCosmosClient } from '@t402/cosmos/exact-direct/client';\n *\n * const client = new ExactDirectCosmosClient(signer);\n * const payload = await client.createPaymentPayload(2, requirements);\n *\n * // Server usage\n * import { ExactDirectCosmosServer } from '@t402/cosmos/exact-direct/server';\n *\n * const server = new ExactDirectCosmosServer();\n * const assetAmount = await server.parsePrice(1.50, 'cosmos:noble-1');\n * ```\n */\n\n// Constants\nexport * from \"./constants.js\";\n\n// Types\nexport * from \"./types.js\";\n\n// Tokens\nexport * from \"./tokens.js\";\n\n// Utilities\nexport * from \"./utils.js\";\n\n// Exact-Direct scheme exports\nexport * from \"./exact-direct/index.js\";\n","/**\n * Cosmos Network Constants\n *\n * This module provides constants for Cosmos blockchain integration including:\n * - CAIP-2 network identifiers (Noble chain)\n * - RPC and REST endpoints\n * - Bech32 prefix configuration\n * - USDC denomination and gas parameters\n */\n\n/**\n * CAIP-2 Network Identifiers for Cosmos (Noble)\n */\nexport const NOBLE_MAINNET_CAIP2 = \"cosmos:noble-1\";\nexport const NOBLE_TESTNET_CAIP2 = \"cosmos:grand-1\";\n\n/**\n * Supported Cosmos networks\n */\nexport const COSMOS_NETWORKS = [NOBLE_MAINNET_CAIP2, NOBLE_TESTNET_CAIP2] as const;\n\nexport type CosmosNetwork = (typeof COSMOS_NETWORKS)[number];\n\n/**\n * Default RPC endpoints\n */\nexport const NOBLE_MAINNET_RPC = \"https://noble-rpc.polkachu.com\";\nexport const NOBLE_TESTNET_RPC = \"https://rpc.testnet.noble.strange.love\";\n\n/**\n * Default REST endpoints\n */\nexport const NOBLE_MAINNET_REST = \"https://noble-api.polkachu.com\";\nexport const NOBLE_TESTNET_REST = \"https://api.testnet.noble.strange.love\";\n\n/**\n * Network RPC endpoint mapping\n */\nexport const NETWORK_RPC_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_RPC,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_RPC,\n};\n\n/**\n * Network REST endpoint mapping\n */\nexport const NETWORK_REST_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_REST,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_REST,\n};\n\n/**\n * Bech32 prefix for Noble addresses\n */\nexport const NOBLE_BECH32_PREFIX = \"noble\";\n\n/**\n * USDC denomination on Noble\n * uusdc = micro-USDC (1 USDC = 1,000,000 uusdc)\n */\nexport const USDC_DENOM = \"uusdc\";\n\n/**\n * Default gas parameters\n */\nexport const DEFAULT_GAS_LIMIT = 200000;\nexport const DEFAULT_GAS_PRICE = \"0.025uusdc\";\nexport const DEFAULT_FEE_AMOUNT = \"5000\"; // 0.005 USDC\n\n/**\n * Cosmos message type for bank send\n */\nexport const MSG_TYPE_SEND = \"/cosmos.bank.v1beta1.MsgSend\";\n\n/**\n * Scheme identifier for exact-direct payments\n */\nexport const SCHEME_EXACT_DIRECT = \"exact-direct\";\n\n/**\n * Maximum transaction age to accept (in milliseconds)\n */\nexport const MAX_TRANSACTION_AGE = 5 * 60 * 1000; // 5 minutes\n\n/**\n * CAIP-2 namespace for Cosmos\n */\nexport const COSMOS_CAIP2_NAMESPACE = \"cosmos\";\n","/**\n * Cosmos Token Registry\n *\n * Defines supported tokens for each Cosmos network (currently Noble USDC).\n */\n\nimport { NOBLE_MAINNET_CAIP2, NOBLE_TESTNET_CAIP2, USDC_DENOM } from \"./constants.js\";\nimport type { TokenConfig } from \"./types.js\";\n\n/**\n * Token registry by network\n */\nexport const TOKEN_REGISTRY: Record<string, TokenConfig[]> = {\n [NOBLE_MAINNET_CAIP2]: [\n {\n denom: USDC_DENOM,\n symbol: \"USDC\",\n name: \"USD Coin\",\n decimals: 6,\n priority: 1,\n },\n ],\n [NOBLE_TESTNET_CAIP2]: [\n {\n denom: USDC_DENOM,\n symbol: \"USDC\",\n name: \"USD Coin (Testnet)\",\n decimals: 6,\n priority: 1,\n },\n ],\n};\n\n/**\n * Get token configuration by symbol\n * @param network - CAIP-2 network identifier\n * @param symbol - Token symbol (e.g., \"USDC\")\n * @returns Token configuration or undefined\n */\nexport function getTokenConfig(network: string, symbol: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return undefined;\n return tokens.find((t) => t.symbol.toUpperCase() === symbol.toUpperCase());\n}\n\n/**\n * Get token configuration by denomination\n * @param network - CAIP-2 network identifier\n * @param denom - Token denomination (e.g., \"uusdc\")\n * @returns Token configuration or undefined\n */\nexport function getTokenByDenom(network: string, denom: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return undefined;\n return tokens.find((t) => t.denom === denom);\n}\n\n/**\n * Get the default token for a network\n * Returns the token with highest priority (lowest priority number)\n * @param network - CAIP-2 network identifier\n * @returns Default token configuration or undefined\n */\nexport function getDefaultToken(network: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens || tokens.length === 0) return undefined;\n return [...tokens].sort((a, b) => a.priority - b.priority)[0];\n}\n\n/**\n * Get all tokens for a network\n * @param network - CAIP-2 network identifier\n * @returns Array of token configurations\n */\nexport function getNetworkTokens(network: string): TokenConfig[] {\n return TOKEN_REGISTRY[network] || [];\n}\n\n/**\n * Check if a network is supported\n * @param network - CAIP-2 network identifier\n */\nexport function isNetworkSupported(network: string): boolean {\n return network in TOKEN_REGISTRY;\n}\n","/**\n * Cosmos Utility Functions\n *\n * Helper functions for Cosmos address validation, network normalization,\n * and amount conversion.\n */\n\nimport {\n COSMOS_CAIP2_NAMESPACE,\n NOBLE_BECH32_PREFIX,\n NETWORK_RPC_ENDPOINTS,\n NETWORK_REST_ENDPOINTS,\n type CosmosNetwork,\n} from \"./constants.js\";\n\n/**\n * Normalize a network identifier to CAIP-2 format\n * @param network - Network identifier (e.g., \"noble-1\", \"cosmos:noble-1\")\n * @returns CAIP-2 formatted network identifier\n */\nexport function normalizeNetwork(network: string): CosmosNetwork {\n // Already in CAIP-2 format\n if (network.startsWith(`${COSMOS_CAIP2_NAMESPACE}:`)) {\n return network as CosmosNetwork;\n }\n // Convert shorthand to CAIP-2\n return `${COSMOS_CAIP2_NAMESPACE}:${network}` as CosmosNetwork;\n}\n\n/**\n * Extract network ID from CAIP-2 identifier\n * @param network - CAIP-2 network identifier\n * @returns Network ID (e.g., \"noble-1\")\n */\nexport function extractNetworkId(network: string): string {\n if (network.includes(\":\")) {\n return network.split(\":\")[1];\n }\n return network;\n}\n\n/**\n * Validate a Cosmos bech32 address with Noble prefix\n * Checks that the address starts with the \"noble\" prefix followed by \"1\"\n * @param address - Address to validate\n * @returns Whether the address is valid\n */\nexport function isValidAddress(address: string): boolean {\n if (!address || address.length < 10) {\n return false;\n }\n return address.startsWith(`${NOBLE_BECH32_PREFIX}1`);\n}\n\n/**\n * Get RPC endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns RPC endpoint URL\n */\nexport function getRpcEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_RPC_ENDPOINTS[normalizedNetwork] || NETWORK_RPC_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Get REST endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns REST endpoint URL\n */\nexport function getRestEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_REST_ENDPOINTS[normalizedNetwork] || NETWORK_REST_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Convert decimal amount to token units (atomic units)\n * @param decimalAmount - Amount with decimals (e.g., \"1.50\")\n * @param decimals - Token decimals\n * @returns Amount in smallest units\n */\nexport function toAtomicUnits(decimalAmount: string | number, decimals: number): bigint {\n const amount = typeof decimalAmount === \"string\" ? parseFloat(decimalAmount) : decimalAmount;\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const multiplier = 10 ** decimals;\n return BigInt(Math.floor(amount * multiplier));\n}\n\n/**\n * Format amount for display (with decimals)\n * @param amount - Amount in smallest units\n * @param decimals - Number of decimal places\n * @returns Formatted amount string\n */\nexport function formatAmount(amount: bigint, decimals: number): string {\n const divisor = BigInt(10 ** decimals);\n const whole = amount / divisor;\n const remainder = amount % divisor;\n const decimal = remainder.toString().padStart(decimals, \"0\").slice(0, 2);\n return `${whole}.${decimal}`;\n}\n\n/**\n * Get the list of supported networks\n * @returns Array of CAIP-2 network identifiers\n */\nexport function getSupportedNetworks(): string[] {\n return Object.keys(NETWORK_RPC_ENDPOINTS);\n}\n","/**\n * Cosmos Client Scheme Implementation - Exact Direct\n *\n * Creates payment payloads for Cosmos MsgSend transfers using the exact-direct scheme.\n * In this scheme, the client executes the bank send directly and provides\n * the transaction hash as proof of payment.\n */\n\nimport type { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport type { ClientCosmosSigner, ExactDirectCosmosPayload } from \"../../types.js\";\nimport { SCHEME_EXACT_DIRECT, USDC_DENOM } from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\n\n/**\n * Configuration for ExactDirectCosmosClient\n */\nexport interface ExactDirectCosmosClientConfig {\n /** Override the default denomination */\n denom?: string;\n}\n\n/**\n * Cosmos client implementation for the Exact-Direct payment scheme.\n *\n * Executes a Cosmos MsgSend and returns the transaction hash as proof.\n */\nexport class ExactDirectCosmosClient implements SchemeNetworkClient {\n readonly scheme = SCHEME_EXACT_DIRECT;\n\n /**\n * Creates a new ExactDirectCosmosClient instance.\n *\n * @param signer - The Cosmos signer for client operations\n * @param config - Optional configuration overrides\n */\n constructor(\n private readonly signer: ClientCosmosSigner,\n private readonly config: ExactDirectCosmosClientConfig = {},\n ) {}\n\n /**\n * Creates a payment payload by executing the transfer.\n *\n * Unlike other schemes where the client creates a signed message for\n * the facilitator to execute, the exact-direct scheme has the client\n * execute the transfer directly. The transaction hash is then used\n * as proof of payment.\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload with transaction hash\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Normalize and validate network\n const network = normalizeNetwork(paymentRequirements.network);\n\n // Validate required fields\n if (!paymentRequirements.payTo) {\n throw new Error(\"PayTo address is required\");\n }\n if (!paymentRequirements.amount) {\n throw new Error(\"Amount is required\");\n }\n\n // Validate addresses\n if (!isValidAddress(paymentRequirements.payTo)) {\n throw new Error(`Invalid recipient address: ${paymentRequirements.payTo}`);\n }\n if (!isValidAddress(this.signer.address)) {\n throw new Error(`Invalid sender address: ${this.signer.address}`);\n }\n\n const recipient = paymentRequirements.payTo;\n const amount = paymentRequirements.amount;\n\n // Determine denomination from extra field, config, or default\n const denom =\n (paymentRequirements.extra?.denom as string) || this.config.denom || USDC_DENOM;\n\n // Execute the transfer\n const txHash = await this.signer.sendTokens(network, recipient, amount, denom);\n\n // Build the payload\n const payload: ExactDirectCosmosPayload = {\n txHash,\n from: this.signer.address,\n to: recipient,\n amount: amount,\n denom,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n}\n","/**\n * Cosmos Server Scheme Implementation - Exact Direct\n *\n * Handles price parsing and payment requirement enhancement for\n * Cosmos (Noble USDC) payments using the exact-direct scheme.\n */\n\nimport type {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n} from \"@t402/core/types\";\nimport { SCHEME_EXACT_DIRECT, NOBLE_BECH32_PREFIX } from \"../../constants.js\";\nimport { getDefaultToken, getTokenConfig, TOKEN_REGISTRY } from \"../../tokens.js\";\nimport { normalizeNetwork, toAtomicUnits } from \"../../utils.js\";\n\n/**\n * Configuration options for ExactDirectCosmosServer\n */\nexport interface ExactDirectCosmosServerConfig {\n /** Preferred token symbol (e.g., \"USDC\"). Defaults to network's highest priority token. */\n preferredToken?: string;\n}\n\n/**\n * Cosmos server implementation for the Exact-Direct payment scheme.\n * Handles price parsing and converts user-friendly amounts to token amounts.\n */\nexport class ExactDirectCosmosServer implements SchemeNetworkServer {\n readonly scheme = SCHEME_EXACT_DIRECT;\n private moneyParsers: MoneyParser[] = [];\n private config: ExactDirectCosmosServerConfig;\n\n constructor(config: ExactDirectCosmosServerConfig = {}) {\n this.config = config;\n }\n\n /**\n * Register a custom money parser in the parser chain.\n * Multiple parsers can be registered - they will be tried in registration order.\n * Each parser receives a decimal amount (e.g., 1.50 for $1.50).\n * If a parser returns null, the next parser in the chain will be tried.\n * The default parser is always the final fallback.\n *\n * @param parser - Custom function to convert amount to AssetAmount (or null to skip)\n * @returns The server instance for chaining\n */\n registerMoneyParser(parser: MoneyParser): ExactDirectCosmosServer {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Parses a price into an asset amount.\n * If price is already an AssetAmount, returns it directly.\n * If price is Money (string | number), parses to decimal and tries custom parsers.\n * Falls back to default conversion if all custom parsers return null.\n *\n * @param price - The price to parse\n * @param network - The network to use\n * @returns Promise that resolves to the parsed asset amount\n */\n async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n // Normalize network to CAIP-2 format\n const normalizedNetwork = normalizeNetwork(network);\n\n // If already an AssetAmount, return it directly\n if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n if (!price.asset) {\n throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n }\n return {\n amount: price.amount,\n asset: price.asset,\n extra: price.extra || {},\n };\n }\n\n // Parse Money to decimal number\n const amount = this.parseMoneyToDecimal(price);\n\n // Try each custom money parser in order\n for (const parser of this.moneyParsers) {\n const result = await parser(amount, normalizedNetwork);\n if (result !== null) {\n return result;\n }\n }\n\n // All custom parsers returned null, use default conversion\n return this.defaultMoneyConversion(amount, normalizedNetwork);\n }\n\n /**\n * Build payment requirements for this scheme/network combination.\n *\n * @param paymentRequirements - Base payment requirements with amount/asset already set\n * @param supportedKind - The supported kind from facilitator's /supported endpoint\n * @param extensionKeys - Extensions supported by the facilitator\n * @returns Enhanced payment requirements ready to be sent to clients\n */\n async enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n t402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n extensionKeys: string[],\n ): Promise<PaymentRequirements> {\n // Mark unused parameters to satisfy linter\n void extensionKeys;\n\n // Start with existing extra fields\n const extra = { ...paymentRequirements.extra };\n\n // Add Cosmos-specific extra fields\n const normalizedNetwork = normalizeNetwork(paymentRequirements.network);\n const token = getDefaultToken(normalizedNetwork);\n\n if (token) {\n extra.bech32Prefix = NOBLE_BECH32_PREFIX;\n extra.denom = token.denom;\n }\n\n // Add any facilitator-provided extra fields\n if (supportedKind.extra?.assetSymbol) {\n extra.assetSymbol = supportedKind.extra.assetSymbol;\n }\n if (supportedKind.extra?.assetDecimals) {\n extra.assetDecimals = supportedKind.extra.assetDecimals;\n }\n if (supportedKind.extra?.assetDenom) {\n extra.assetDenom = supportedKind.extra.assetDenom;\n }\n\n return {\n ...paymentRequirements,\n extra,\n };\n }\n\n /**\n * Parse Money (string | number) to a decimal number.\n * Handles formats like \"$1.50\", \"1.50\", 1.50, etc.\n */\n private parseMoneyToDecimal(money: string | number): number {\n if (typeof money === \"number\") {\n return money;\n }\n\n // Remove $ sign and whitespace, then parse\n const cleanMoney = money.replace(/^\\$/, \"\").trim();\n const amount = parseFloat(cleanMoney);\n\n if (isNaN(amount)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n return amount;\n }\n\n /**\n * Default money conversion implementation.\n * Converts decimal amount to the preferred token on the specified network.\n */\n private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n const token = this.getDefaultAsset(network);\n\n // Convert decimal amount to token amount\n const tokenAmount = toAtomicUnits(amount, token.decimals);\n\n return {\n amount: tokenAmount.toString(),\n asset: token.denom,\n extra: {\n symbol: token.symbol,\n name: token.name,\n decimals: token.decimals,\n },\n };\n }\n\n /**\n * Get the default asset info for a network.\n * Priority: configured preferredToken > network default\n */\n private getDefaultAsset(network: Network): {\n denom: string;\n symbol: string;\n name: string;\n decimals: number;\n } {\n // If a preferred token is configured, try to use it\n if (this.config.preferredToken) {\n const preferred = getTokenConfig(network, this.config.preferredToken);\n if (preferred) return preferred;\n }\n\n // Use the network's default token (sorted by priority)\n const defaultToken = getDefaultToken(network);\n if (defaultToken) return defaultToken;\n\n throw new Error(`No tokens configured for network ${network}`);\n }\n\n /**\n * Get all supported networks\n */\n static getSupportedNetworks(): string[] {\n return Object.keys(TOKEN_REGISTRY);\n }\n\n /**\n * Check if a network is supported\n */\n static isNetworkSupported(network: string): boolean {\n return network in TOKEN_REGISTRY;\n }\n}\n","/**\n * Cosmos Facilitator Scheme Implementation - Exact Direct\n *\n * Verifies and settles Cosmos (Noble USDC) payments using the exact-direct scheme.\n * The facilitator verifies that the client's transaction was successful\n * and matches the payment requirements.\n */\n\nimport type {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport type { FacilitatorCosmosSigner, ExactDirectCosmosPayload, MsgSend } from \"../../types.js\";\nimport { SCHEME_EXACT_DIRECT, COSMOS_CAIP2_NAMESPACE, MAX_TRANSACTION_AGE, MSG_TYPE_SEND } from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\nimport { getDefaultToken } from \"../../tokens.js\";\n\n/**\n * Configuration for ExactDirectCosmosFacilitator\n */\nexport interface ExactDirectCosmosFacilitatorConfig {\n /** Maximum age of a transaction to accept (in milliseconds) */\n maxTransactionAge?: number;\n /** Duration to cache used transaction hashes (in milliseconds) */\n usedTxCacheDuration?: number;\n}\n\n/**\n * Cosmos facilitator implementation for the Exact-Direct payment scheme.\n * Verifies transaction proofs and confirms payments.\n */\nexport class ExactDirectCosmosFacilitator implements SchemeNetworkFacilitator {\n readonly scheme = SCHEME_EXACT_DIRECT;\n readonly caipFamily = `${COSMOS_CAIP2_NAMESPACE}:*`;\n\n private readonly config: Required<ExactDirectCosmosFacilitatorConfig>;\n private usedTxs: Map<string, number> = new Map();\n\n constructor(\n private readonly signer: FacilitatorCosmosSigner,\n config?: ExactDirectCosmosFacilitatorConfig,\n ) {\n this.config = {\n maxTransactionAge: config?.maxTransactionAge ?? MAX_TRANSACTION_AGE,\n usedTxCacheDuration: config?.usedTxCacheDuration ?? 24 * 60 * 60 * 1000, // 24 hours\n };\n\n // Start cleanup interval\n this.startCleanupInterval();\n }\n\n /**\n * Get extra data for a supported kind\n */\n getExtra(network: Network): Record<string, unknown> | undefined {\n const token = getDefaultToken(network);\n if (!token) {\n return undefined;\n }\n return {\n assetSymbol: token.symbol,\n assetDecimals: token.decimals,\n assetDenom: token.denom,\n };\n }\n\n /**\n * Get signer addresses for a network\n */\n getSigners(network: Network): string[] {\n return this.signer.getAddresses(network);\n }\n\n /**\n * Verify a payment payload\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const network = normalizeNetwork(requirements.network);\n\n // Validate scheme\n if (payload.accepted.scheme !== SCHEME_EXACT_DIRECT) {\n return {\n isValid: false,\n invalidReason: \"invalid_scheme\",\n };\n }\n\n // Validate network\n if (normalizeNetwork(payload.accepted.network) !== network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n };\n }\n\n // Parse payload\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n if (!cosmosPayload.txHash) {\n return {\n isValid: false,\n invalidReason: \"missing_tx_hash\",\n };\n }\n if (!cosmosPayload.from || !isValidAddress(cosmosPayload.from)) {\n return {\n isValid: false,\n invalidReason: \"invalid_from_address\",\n };\n }\n\n // Check for replay attack\n if (this.isTxUsed(cosmosPayload.txHash)) {\n return {\n isValid: false,\n invalidReason: \"transaction_already_used\",\n payer: cosmosPayload.from,\n };\n }\n\n try {\n // Query the transaction\n const tx = await this.signer.queryTransaction(network, cosmosPayload.txHash);\n\n // Check transaction succeeded (code 0 = success)\n if (tx.code !== 0) {\n return {\n isValid: false,\n invalidReason: \"transaction_failed\",\n payer: cosmosPayload.from,\n };\n }\n\n // Find the MsgSend in the transaction messages\n const msgSend = this.findMsgSend(tx.tx.body.messages);\n if (!msgSend) {\n return {\n isValid: false,\n invalidReason: \"no_msg_send_found\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify recipient\n if (msgSend.toAddress !== requirements.payTo) {\n return {\n isValid: false,\n invalidReason: \"wrong_recipient\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify sender matches payload\n if (msgSend.fromAddress !== cosmosPayload.from) {\n return {\n isValid: false,\n invalidReason: \"sender_mismatch\",\n payer: cosmosPayload.from,\n };\n }\n\n // Determine expected denom\n const expectedDenom = (requirements.extra?.denom as string) || requirements.asset;\n\n // Verify amount and denomination\n const coin = this.getAmountByDenom(msgSend, expectedDenom);\n if (!coin) {\n return {\n isValid: false,\n invalidReason: \"wrong_denomination\",\n payer: cosmosPayload.from,\n };\n }\n\n const txAmount = BigInt(coin.amount);\n const requiredAmount = BigInt(requirements.amount);\n if (txAmount < requiredAmount) {\n return {\n isValid: false,\n invalidReason: \"insufficient_amount\",\n payer: cosmosPayload.from,\n };\n }\n\n // Mark transaction as used\n this.markTxUsed(cosmosPayload.txHash);\n\n return {\n isValid: true,\n payer: cosmosPayload.from,\n };\n } catch {\n return {\n isValid: false,\n invalidReason: \"transaction_not_found\",\n payer: cosmosPayload.from,\n };\n }\n }\n\n /**\n * Settle a payment - for exact-direct, the transfer is already complete\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n // Verify first\n const verifyResult = await this.verify(payload, requirements);\n if (!verifyResult.isValid) {\n return {\n success: false,\n errorReason: verifyResult.invalidReason || \"verification_failed\",\n payer: verifyResult.payer,\n transaction: \"\",\n network: normalizeNetwork(requirements.network),\n };\n }\n\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n\n // For exact-direct, settlement is already complete\n return {\n success: true,\n transaction: cosmosPayload.txHash,\n network: normalizeNetwork(requirements.network),\n payer: cosmosPayload.from,\n };\n }\n\n /**\n * Find a MsgSend in transaction messages\n */\n private findMsgSend(messages: MsgSend[]): MsgSend | null {\n for (const msg of messages) {\n if (msg[\"@type\"] === MSG_TYPE_SEND || (!msg[\"@type\"] && msg.fromAddress && msg.toAddress)) {\n return msg;\n }\n }\n return null;\n }\n\n /**\n * Get a specific coin amount from a MsgSend by denomination\n */\n private getAmountByDenom(msg: MsgSend, denom: string): { denom: string; amount: string } | null {\n for (const coin of msg.amount) {\n if (coin.denom === denom) {\n return coin;\n }\n }\n return null;\n }\n\n /**\n * Check if a transaction has been used\n */\n private isTxUsed(txHash: string): boolean {\n return this.usedTxs.has(txHash);\n }\n\n /**\n * Mark a transaction as used\n */\n private markTxUsed(txHash: string): void {\n this.usedTxs.set(txHash, Date.now());\n }\n\n /**\n * Start the cleanup interval for used transactions\n */\n private startCleanupInterval(): void {\n setInterval(\n () => {\n const cutoff = Date.now() - this.config.usedTxCacheDuration;\n for (const [txHash, usedAt] of this.usedTxs.entries()) {\n if (usedAt < cutoff) {\n this.usedTxs.delete(txHash);\n }\n }\n },\n 60 * 60 * 1000,\n ); // Cleanup every hour\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACaO,IAAM,sBAAsB;AAC5B,IAAM,sBAAsB;AAK5B,IAAM,kBAAkB,CAAC,qBAAqB,mBAAmB;AAOjE,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAK1B,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAK3B,IAAM,wBAAgD;AAAA,EAC3D,CAAC,mBAAmB,GAAG;AAAA,EACvB,CAAC,mBAAmB,GAAG;AACzB;AAKO,IAAM,yBAAiD;AAAA,EAC5D,CAAC,mBAAmB,GAAG;AAAA,EACvB,CAAC,mBAAmB,GAAG;AACzB;AAKO,IAAM,sBAAsB;AAM5B,IAAM,aAAa;AAKnB,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB;AAK3B,IAAM,gBAAgB;AAKtB,IAAM,sBAAsB;AAK5B,IAAM,sBAAsB,IAAI,KAAK;AAKrC,IAAM,yBAAyB;;;AC3E/B,IAAM,iBAAgD;AAAA,EAC3D,CAAC,mBAAmB,GAAG;AAAA,IACrB;AAAA,MACE,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,CAAC,mBAAmB,GAAG;AAAA,IACrB;AAAA,MACE,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,EACF;AACF;AAQO,SAAS,eAAe,SAAiB,QAAyC;AACvF,QAAM,SAAS,eAAe,OAAO;AACrC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY,MAAM,OAAO,YAAY,CAAC;AAC3E;AAQO,SAAS,gBAAgB,SAAiB,OAAwC;AACvF,QAAM,SAAS,eAAe,OAAO;AACrC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK;AAC7C;AAQO,SAAS,gBAAgB,SAA0C;AACxE,QAAM,SAAS,eAAe,OAAO;AACrC,MAAI,CAAC,UAAU,OAAO,WAAW,EAAG,QAAO;AAC3C,SAAO,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;AAC9D;AAOO,SAAS,iBAAiB,SAAgC;AAC/D,SAAO,eAAe,OAAO,KAAK,CAAC;AACrC;AAMO,SAAS,mBAAmB,SAA0B;AAC3D,SAAO,WAAW;AACpB;;;AChEO,SAAS,iBAAiB,SAAgC;AAE/D,MAAI,QAAQ,WAAW,GAAG,sBAAsB,GAAG,GAAG;AACpD,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,sBAAsB,IAAI,OAAO;AAC7C;AAOO,SAAS,iBAAiB,SAAyB;AACxD,MAAI,QAAQ,SAAS,GAAG,GAAG;AACzB,WAAO,QAAQ,MAAM,GAAG,EAAE,CAAC;AAAA,EAC7B;AACA,SAAO;AACT;AAQO,SAAS,eAAe,SAA0B;AACvD,MAAI,CAAC,WAAW,QAAQ,SAAS,IAAI;AACnC,WAAO;AAAA,EACT;AACA,SAAO,QAAQ,WAAW,GAAG,mBAAmB,GAAG;AACrD;AAOO,SAAS,eAAe,SAAyB;AACtD,QAAM,oBAAoB,iBAAiB,OAAO;AAClD,SAAO,sBAAsB,iBAAiB,KAAK,sBAAsB,gBAAgB;AAC3F;AAOO,SAAS,gBAAgB,SAAyB;AACvD,QAAM,oBAAoB,iBAAiB,OAAO;AAClD,SAAO,uBAAuB,iBAAiB,KAAK,uBAAuB,gBAAgB;AAC7F;AAQO,SAAS,cAAc,eAAgC,UAA0B;AACtF,QAAM,SAAS,OAAO,kBAAkB,WAAW,WAAW,aAAa,IAAI;AAC/E,MAAI,MAAM,MAAM,GAAG;AACjB,UAAM,IAAI,MAAM,mBAAmB,aAAa,EAAE;AAAA,EACpD;AACA,QAAM,aAAa,MAAM;AACzB,SAAO,OAAO,KAAK,MAAM,SAAS,UAAU,CAAC;AAC/C;AAQO,SAAS,aAAa,QAAgB,UAA0B;AACrE,QAAM,UAAU,OAAO,MAAM,QAAQ;AACrC,QAAM,QAAQ,SAAS;AACvB,QAAM,YAAY,SAAS;AAC3B,QAAM,UAAU,UAAU,SAAS,EAAE,SAAS,UAAU,GAAG,EAAE,MAAM,GAAG,CAAC;AACvE,SAAO,GAAG,KAAK,IAAI,OAAO;AAC5B;AAMO,SAAS,uBAAiC;AAC/C,SAAO,OAAO,KAAK,qBAAqB;AAC1C;;;ACnFO,IAAM,0BAAN,MAA6D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlE,YACmB,QACA,SAAwC,CAAC,GAC1D;AAFiB;AACA;AAVnB,SAAS,SAAS;AAAA,EAWf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcH,MAAM,qBACJ,aACA,qBAC0D;AAE1D,UAAM,UAAU,iBAAiB,oBAAoB,OAAO;AAG5D,QAAI,CAAC,oBAAoB,OAAO;AAC9B,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,QAAI,CAAC,oBAAoB,QAAQ;AAC/B,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AAGA,QAAI,CAAC,eAAe,oBAAoB,KAAK,GAAG;AAC9C,YAAM,IAAI,MAAM,8BAA8B,oBAAoB,KAAK,EAAE;AAAA,IAC3E;AACA,QAAI,CAAC,eAAe,KAAK,OAAO,OAAO,GAAG;AACxC,YAAM,IAAI,MAAM,2BAA2B,KAAK,OAAO,OAAO,EAAE;AAAA,IAClE;AAEA,UAAM,YAAY,oBAAoB;AACtC,UAAM,SAAS,oBAAoB;AAGnC,UAAM,QACH,oBAAoB,OAAO,SAAoB,KAAK,OAAO,SAAS;AAGvE,UAAM,SAAS,MAAM,KAAK,OAAO,WAAW,SAAS,WAAW,QAAQ,KAAK;AAG7E,UAAM,UAAoC;AAAA,MACxC;AAAA,MACA,MAAM,KAAK,OAAO;AAAA,MAClB,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;ACpEO,IAAM,0BAAN,MAA6D;AAAA,EAKlE,YAAY,SAAwC,CAAC,GAAG;AAJxD,SAAS,SAAS;AAClB,SAAQ,eAA8B,CAAC;AAIrC,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,oBAAoB,QAA8C;AAChE,SAAK,aAAa,KAAK,MAAM;AAC7B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,WAAW,OAAc,SAAwC;AAErE,UAAM,oBAAoB,iBAAiB,OAAO;AAGlD,QAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY,OAAO;AACpE,UAAI,CAAC,MAAM,OAAO;AAChB,cAAM,IAAI,MAAM,8DAA8D,OAAO,EAAE;AAAA,MACzF;AACA,aAAO;AAAA,QACL,QAAQ,MAAM;AAAA,QACd,OAAO,MAAM;AAAA,QACb,OAAO,MAAM,SAAS,CAAC;AAAA,MACzB;AAAA,IACF;AAGA,UAAM,SAAS,KAAK,oBAAoB,KAAK;AAG7C,eAAW,UAAU,KAAK,cAAc;AACtC,YAAM,SAAS,MAAM,OAAO,QAAQ,iBAAiB;AACrD,UAAI,WAAW,MAAM;AACnB,eAAO;AAAA,MACT;AAAA,IACF;AAGA,WAAO,KAAK,uBAAuB,QAAQ,iBAAiB;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,2BACJ,qBACA,eAMA,eAC8B;AAE9B,SAAK;AAGL,UAAM,QAAQ,EAAE,GAAG,oBAAoB,MAAM;AAG7C,UAAM,oBAAoB,iBAAiB,oBAAoB,OAAO;AACtE,UAAM,QAAQ,gBAAgB,iBAAiB;AAE/C,QAAI,OAAO;AACT,YAAM,eAAe;AACrB,YAAM,QAAQ,MAAM;AAAA,IACtB;AAGA,QAAI,cAAc,OAAO,aAAa;AACpC,YAAM,cAAc,cAAc,MAAM;AAAA,IAC1C;AACA,QAAI,cAAc,OAAO,eAAe;AACtC,YAAM,gBAAgB,cAAc,MAAM;AAAA,IAC5C;AACA,QAAI,cAAc,OAAO,YAAY;AACnC,YAAM,aAAa,cAAc,MAAM;AAAA,IACzC;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,oBAAoB,OAAgC;AAC1D,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,MAAM,QAAQ,OAAO,EAAE,EAAE,KAAK;AACjD,UAAM,SAAS,WAAW,UAAU;AAEpC,QAAI,MAAM,MAAM,GAAG;AACjB,YAAM,IAAI,MAAM,yBAAyB,KAAK,EAAE;AAAA,IAClD;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,uBAAuB,QAAgB,SAA+B;AAC5E,UAAM,QAAQ,KAAK,gBAAgB,OAAO;AAG1C,UAAM,cAAc,cAAc,QAAQ,MAAM,QAAQ;AAExD,WAAO;AAAA,MACL,QAAQ,YAAY,SAAS;AAAA,MAC7B,OAAO,MAAM;AAAA,MACb,OAAO;AAAA,QACL,QAAQ,MAAM;AAAA,QACd,MAAM,MAAM;AAAA,QACZ,UAAU,MAAM;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,gBAAgB,SAKtB;AAEA,QAAI,KAAK,OAAO,gBAAgB;AAC9B,YAAM,YAAY,eAAe,SAAS,KAAK,OAAO,cAAc;AACpE,UAAI,UAAW,QAAO;AAAA,IACxB;AAGA,UAAM,eAAe,gBAAgB,OAAO;AAC5C,QAAI,aAAc,QAAO;AAEzB,UAAM,IAAI,MAAM,oCAAoC,OAAO,EAAE;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,uBAAiC;AACtC,WAAO,OAAO,KAAK,cAAc;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,mBAAmB,SAA0B;AAClD,WAAO,WAAW;AAAA,EACpB;AACF;;;AC5LO,IAAM,+BAAN,MAAuE;AAAA,EAO5E,YACmB,QACjB,QACA;AAFiB;AAPnB,SAAS,SAAS;AAClB,SAAS,aAAa,GAAG,sBAAsB;AAG/C,SAAQ,UAA+B,oBAAI,IAAI;AAM7C,SAAK,SAAS;AAAA,MACZ,mBAAmB,QAAQ,qBAAqB;AAAA,MAChD,qBAAqB,QAAQ,uBAAuB,KAAK,KAAK,KAAK;AAAA;AAAA,IACrE;AAGA,SAAK,qBAAqB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,SAAuD;AAC9D,UAAM,QAAQ,gBAAgB,OAAO;AACrC,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL,aAAa,MAAM;AAAA,MACnB,eAAe,MAAM;AAAA,MACrB,YAAY,MAAM;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,SAA4B;AACrC,WAAO,KAAK,OAAO,aAAa,OAAO;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OACJ,SACA,cACyB;AACzB,UAAM,UAAU,iBAAiB,aAAa,OAAO;AAGrD,QAAI,QAAQ,SAAS,WAAW,qBAAqB;AACnD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,MACjB;AAAA,IACF;AAGA,QAAI,iBAAiB,QAAQ,SAAS,OAAO,MAAM,SAAS;AAC1D,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,MACjB;AAAA,IACF;AAGA,UAAM,gBAAgB,QAAQ;AAC9B,QAAI,CAAC,cAAc,QAAQ;AACzB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,MACjB;AAAA,IACF;AACA,QAAI,CAAC,cAAc,QAAQ,CAAC,eAAe,cAAc,IAAI,GAAG;AAC9D,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,MACjB;AAAA,IACF;AAGA,QAAI,KAAK,SAAS,cAAc,MAAM,GAAG;AACvC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,KAAK,MAAM,KAAK,OAAO,iBAAiB,SAAS,cAAc,MAAM;AAG3E,UAAI,GAAG,SAAS,GAAG;AACjB,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,cAAc;AAAA,QACvB;AAAA,MACF;AAGA,YAAM,UAAU,KAAK,YAAY,GAAG,GAAG,KAAK,QAAQ;AACpD,UAAI,CAAC,SAAS;AACZ,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,cAAc;AAAA,QACvB;AAAA,MACF;AAGA,UAAI,QAAQ,cAAc,aAAa,OAAO;AAC5C,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,cAAc;AAAA,QACvB;AAAA,MACF;AAGA,UAAI,QAAQ,gBAAgB,cAAc,MAAM;AAC9C,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,cAAc;AAAA,QACvB;AAAA,MACF;AAGA,YAAM,gBAAiB,aAAa,OAAO,SAAoB,aAAa;AAG5E,YAAM,OAAO,KAAK,iBAAiB,SAAS,aAAa;AACzD,UAAI,CAAC,MAAM;AACT,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,cAAc;AAAA,QACvB;AAAA,MACF;AAEA,YAAM,WAAW,OAAO,KAAK,MAAM;AACnC,YAAM,iBAAiB,OAAO,aAAa,MAAM;AACjD,UAAI,WAAW,gBAAgB;AAC7B,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,cAAc;AAAA,QACvB;AAAA,MACF;AAGA,WAAK,WAAW,cAAc,MAAM;AAEpC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,cAAc;AAAA,MACvB;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OACJ,SACA,cACyB;AAEzB,UAAM,eAAe,MAAM,KAAK,OAAO,SAAS,YAAY;AAC5D,QAAI,CAAC,aAAa,SAAS;AACzB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa,aAAa,iBAAiB;AAAA,QAC3C,OAAO,aAAa;AAAA,QACpB,aAAa;AAAA,QACb,SAAS,iBAAiB,aAAa,OAAO;AAAA,MAChD;AAAA,IACF;AAEA,UAAM,gBAAgB,QAAQ;AAG9B,WAAO;AAAA,MACL,SAAS;AAAA,MACT,aAAa,cAAc;AAAA,MAC3B,SAAS,iBAAiB,aAAa,OAAO;AAAA,MAC9C,OAAO,cAAc;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,UAAqC;AACvD,eAAW,OAAO,UAAU;AAC1B,UAAI,IAAI,OAAO,MAAM,iBAAkB,CAAC,IAAI,OAAO,KAAK,IAAI,eAAe,IAAI,WAAY;AACzF,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,KAAc,OAAyD;AAC9F,eAAW,QAAQ,IAAI,QAAQ;AAC7B,UAAI,KAAK,UAAU,OAAO;AACxB,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,SAAS,QAAyB;AACxC,WAAO,KAAK,QAAQ,IAAI,MAAM;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAW,QAAsB;AACvC,SAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,CAAC;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAA6B;AACnC;AAAA,MACE,MAAM;AACJ,cAAM,SAAS,KAAK,IAAI,IAAI,KAAK,OAAO;AACxC,mBAAW,CAAC,QAAQ,MAAM,KAAK,KAAK,QAAQ,QAAQ,GAAG;AACrD,cAAI,SAAS,QAAQ;AACnB,iBAAK,QAAQ,OAAO,MAAM;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAAA,MACA,KAAK,KAAK;AAAA,IACZ;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/constants.ts","../../src/tokens.ts","../../src/utils.ts","../../src/exact-direct/client/scheme.ts","../../src/exact-direct/server/scheme.ts","../../src/exact-direct/facilitator/scheme.ts"],"sourcesContent":["/**\n * @t402/cosmos - Cosmos (Noble USDC) Implementation for T402\n *\n * This package provides Cosmos blockchain support for the T402 payment protocol.\n * It implements the exact-direct scheme using Noble's native USDC via MsgSend.\n *\n * @example\n * ```typescript\n * // Client usage\n * import { ExactDirectCosmosClient } from '@t402/cosmos/exact-direct/client';\n *\n * const client = new ExactDirectCosmosClient(signer);\n * const payload = await client.createPaymentPayload(2, requirements);\n *\n * // Server usage\n * import { ExactDirectCosmosServer } from '@t402/cosmos/exact-direct/server';\n *\n * const server = new ExactDirectCosmosServer();\n * const assetAmount = await server.parsePrice(1.50, 'cosmos:noble-1');\n * ```\n */\n\n// Constants\nexport * from \"./constants.js\";\n\n// Types\nexport * from \"./types.js\";\n\n// Tokens\nexport * from \"./tokens.js\";\n\n// Utilities\nexport * from \"./utils.js\";\n\n// Exact-Direct scheme exports\nexport * from \"./exact-direct/index.js\";\n","/**\n * Cosmos Network Constants\n *\n * This module provides constants for Cosmos blockchain integration including:\n * - CAIP-2 network identifiers (Noble chain)\n * - RPC and REST endpoints\n * - Bech32 prefix configuration\n * - USDC denomination and gas parameters\n */\n\n/**\n * CAIP-2 Network Identifiers for Cosmos (Noble)\n */\nexport const NOBLE_MAINNET_CAIP2 = \"cosmos:noble-1\";\nexport const NOBLE_TESTNET_CAIP2 = \"cosmos:grand-1\";\n\n/**\n * Supported Cosmos networks\n */\nexport const COSMOS_NETWORKS = [NOBLE_MAINNET_CAIP2, NOBLE_TESTNET_CAIP2] as const;\n\nexport type CosmosNetwork = (typeof COSMOS_NETWORKS)[number];\n\n/**\n * Default RPC endpoints\n */\nexport const NOBLE_MAINNET_RPC = \"https://noble-rpc.polkachu.com\";\nexport const NOBLE_TESTNET_RPC = \"https://rpc.testnet.noble.strange.love\";\n\n/**\n * Default REST endpoints\n */\nexport const NOBLE_MAINNET_REST = \"https://noble-api.polkachu.com\";\nexport const NOBLE_TESTNET_REST = \"https://api.testnet.noble.strange.love\";\n\n/**\n * Network RPC endpoint mapping\n */\nexport const NETWORK_RPC_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_RPC,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_RPC,\n};\n\n/**\n * Network REST endpoint mapping\n */\nexport const NETWORK_REST_ENDPOINTS: Record<string, string> = {\n [NOBLE_MAINNET_CAIP2]: NOBLE_MAINNET_REST,\n [NOBLE_TESTNET_CAIP2]: NOBLE_TESTNET_REST,\n};\n\n/**\n * Bech32 prefix for Noble addresses\n */\nexport const NOBLE_BECH32_PREFIX = \"noble\";\n\n/**\n * USDC denomination on Noble\n * uusdc = micro-USDC (1 USDC = 1,000,000 uusdc)\n */\nexport const USDC_DENOM = \"uusdc\";\n\n/**\n * Default gas parameters\n */\nexport const DEFAULT_GAS_LIMIT = 200000;\nexport const DEFAULT_GAS_PRICE = \"0.025uusdc\";\nexport const DEFAULT_FEE_AMOUNT = \"5000\"; // 0.005 USDC\n\n/**\n * Cosmos message type for bank send\n */\nexport const MSG_TYPE_SEND = \"/cosmos.bank.v1beta1.MsgSend\";\n\n/**\n * Scheme identifier for exact-direct payments\n */\nexport const SCHEME_EXACT_DIRECT = \"exact-direct\";\n\n/**\n * Maximum transaction age to accept (in milliseconds)\n */\nexport const MAX_TRANSACTION_AGE = 5 * 60 * 1000; // 5 minutes\n\n/**\n * CAIP-2 namespace for Cosmos\n */\nexport const COSMOS_CAIP2_NAMESPACE = \"cosmos\";\n","/**\n * Cosmos Token Registry\n *\n * Defines supported tokens for each Cosmos network (currently Noble USDC).\n */\n\nimport { NOBLE_MAINNET_CAIP2, NOBLE_TESTNET_CAIP2, USDC_DENOM } from \"./constants.js\";\nimport type { TokenConfig } from \"./types.js\";\n\n/**\n * Token registry by network\n */\nexport const TOKEN_REGISTRY: Record<string, TokenConfig[]> = {\n [NOBLE_MAINNET_CAIP2]: [\n {\n denom: USDC_DENOM,\n symbol: \"USDC\",\n name: \"USD Coin\",\n decimals: 6,\n priority: 1,\n },\n ],\n [NOBLE_TESTNET_CAIP2]: [\n {\n denom: USDC_DENOM,\n symbol: \"USDC\",\n name: \"USD Coin (Testnet)\",\n decimals: 6,\n priority: 1,\n },\n ],\n};\n\n/**\n * Get token configuration by symbol\n * @param network - CAIP-2 network identifier\n * @param symbol - Token symbol (e.g., \"USDC\")\n * @returns Token configuration or undefined\n */\nexport function getTokenConfig(network: string, symbol: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return undefined;\n return tokens.find((t) => t.symbol.toUpperCase() === symbol.toUpperCase());\n}\n\n/**\n * Get token configuration by denomination\n * @param network - CAIP-2 network identifier\n * @param denom - Token denomination (e.g., \"uusdc\")\n * @returns Token configuration or undefined\n */\nexport function getTokenByDenom(network: string, denom: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return undefined;\n return tokens.find((t) => t.denom === denom);\n}\n\n/**\n * Get the default token for a network\n * Returns the token with highest priority (lowest priority number)\n * @param network - CAIP-2 network identifier\n * @returns Default token configuration or undefined\n */\nexport function getDefaultToken(network: string): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens || tokens.length === 0) return undefined;\n return [...tokens].sort((a, b) => a.priority - b.priority)[0];\n}\n\n/**\n * Get all tokens for a network\n * @param network - CAIP-2 network identifier\n * @returns Array of token configurations\n */\nexport function getNetworkTokens(network: string): TokenConfig[] {\n return TOKEN_REGISTRY[network] || [];\n}\n\n/**\n * Check if a network is supported\n * @param network - CAIP-2 network identifier\n */\nexport function isNetworkSupported(network: string): boolean {\n return network in TOKEN_REGISTRY;\n}\n","/**\n * Cosmos Utility Functions\n *\n * Helper functions for Cosmos address validation, network normalization,\n * and amount conversion.\n */\n\nimport {\n COSMOS_CAIP2_NAMESPACE,\n NOBLE_BECH32_PREFIX,\n NETWORK_RPC_ENDPOINTS,\n NETWORK_REST_ENDPOINTS,\n type CosmosNetwork,\n} from \"./constants.js\";\n\n/**\n * Normalize a network identifier to CAIP-2 format\n * @param network - Network identifier (e.g., \"noble-1\", \"cosmos:noble-1\")\n * @returns CAIP-2 formatted network identifier\n */\nexport function normalizeNetwork(network: string): CosmosNetwork {\n // Already in CAIP-2 format\n if (network.startsWith(`${COSMOS_CAIP2_NAMESPACE}:`)) {\n return network as CosmosNetwork;\n }\n // Convert shorthand to CAIP-2\n return `${COSMOS_CAIP2_NAMESPACE}:${network}` as CosmosNetwork;\n}\n\n/**\n * Extract network ID from CAIP-2 identifier\n * @param network - CAIP-2 network identifier\n * @returns Network ID (e.g., \"noble-1\")\n */\nexport function extractNetworkId(network: string): string {\n if (network.includes(\":\")) {\n return network.split(\":\")[1];\n }\n return network;\n}\n\n/**\n * Validate a Cosmos bech32 address with Noble prefix\n * Checks that the address starts with the \"noble\" prefix followed by \"1\"\n * @param address - Address to validate\n * @returns Whether the address is valid\n */\nexport function isValidAddress(address: string): boolean {\n if (!address || address.length < 10) {\n return false;\n }\n return address.startsWith(`${NOBLE_BECH32_PREFIX}1`);\n}\n\n/**\n * Get RPC endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns RPC endpoint URL\n */\nexport function getRpcEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_RPC_ENDPOINTS[normalizedNetwork] || NETWORK_RPC_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Get REST endpoint for a network\n * @param network - CAIP-2 network identifier\n * @returns REST endpoint URL\n */\nexport function getRestEndpoint(network: string): string {\n const normalizedNetwork = normalizeNetwork(network);\n return NETWORK_REST_ENDPOINTS[normalizedNetwork] || NETWORK_REST_ENDPOINTS[\"cosmos:noble-1\"];\n}\n\n/**\n * Convert decimal amount to token units (atomic units)\n * @param decimalAmount - Amount with decimals (e.g., \"1.50\")\n * @param decimals - Token decimals\n * @returns Amount in smallest units\n */\nexport function toAtomicUnits(decimalAmount: string | number, decimals: number): bigint {\n const amount = typeof decimalAmount === \"string\" ? parseFloat(decimalAmount) : decimalAmount;\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const multiplier = 10 ** decimals;\n return BigInt(Math.floor(amount * multiplier));\n}\n\n/**\n * Format amount for display (with decimals)\n * @param amount - Amount in smallest units\n * @param decimals - Number of decimal places\n * @returns Formatted amount string\n */\nexport function formatAmount(amount: bigint, decimals: number): string {\n const divisor = BigInt(10 ** decimals);\n const whole = amount / divisor;\n const remainder = amount % divisor;\n const decimal = remainder.toString().padStart(decimals, \"0\").slice(0, 2);\n return `${whole}.${decimal}`;\n}\n\n/**\n * Get the list of supported networks\n * @returns Array of CAIP-2 network identifiers\n */\nexport function getSupportedNetworks(): string[] {\n return Object.keys(NETWORK_RPC_ENDPOINTS);\n}\n","/**\n * Cosmos Client Scheme Implementation - Exact Direct\n *\n * Creates payment payloads for Cosmos MsgSend transfers using the exact-direct scheme.\n * In this scheme, the client executes the bank send directly and provides\n * the transaction hash as proof of payment.\n */\n\nimport type { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport type { ClientCosmosSigner, ExactDirectCosmosPayload } from \"../../types.js\";\nimport { SCHEME_EXACT_DIRECT, USDC_DENOM } from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\n\n/**\n * Configuration for ExactDirectCosmosClient\n */\nexport interface ExactDirectCosmosClientConfig {\n /** Override the default denomination */\n denom?: string;\n}\n\n/**\n * Cosmos client implementation for the Exact-Direct payment scheme.\n *\n * Executes a Cosmos MsgSend and returns the transaction hash as proof.\n */\nexport class ExactDirectCosmosClient implements SchemeNetworkClient {\n readonly scheme = SCHEME_EXACT_DIRECT;\n\n /**\n * Creates a new ExactDirectCosmosClient instance.\n *\n * @param signer - The Cosmos signer for client operations\n * @param config - Optional configuration overrides\n */\n constructor(\n private readonly signer: ClientCosmosSigner,\n private readonly config: ExactDirectCosmosClientConfig = {},\n ) {}\n\n /**\n * Creates a payment payload by executing the transfer.\n *\n * Unlike other schemes where the client creates a signed message for\n * the facilitator to execute, the exact-direct scheme has the client\n * execute the transfer directly. The transaction hash is then used\n * as proof of payment.\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload with transaction hash\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Normalize and validate network\n const network = normalizeNetwork(paymentRequirements.network);\n\n // Validate required fields\n if (!paymentRequirements.payTo) {\n throw new Error(\"PayTo address is required\");\n }\n if (!paymentRequirements.amount) {\n throw new Error(\"Amount is required\");\n }\n\n // Validate addresses\n if (!isValidAddress(paymentRequirements.payTo)) {\n throw new Error(`Invalid recipient address: ${paymentRequirements.payTo}`);\n }\n if (!isValidAddress(this.signer.address)) {\n throw new Error(`Invalid sender address: ${this.signer.address}`);\n }\n\n const recipient = paymentRequirements.payTo;\n const amount = paymentRequirements.amount;\n\n // Determine denomination from extra field, config, or default\n const denom = (paymentRequirements.extra?.denom as string) || this.config.denom || USDC_DENOM;\n\n // Execute the transfer\n const txHash = await this.signer.sendTokens(network, recipient, amount, denom);\n\n // Build the payload\n const payload: ExactDirectCosmosPayload = {\n txHash,\n from: this.signer.address,\n to: recipient,\n amount: amount,\n denom,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n}\n","/**\n * Cosmos Server Scheme Implementation - Exact Direct\n *\n * Handles price parsing and payment requirement enhancement for\n * Cosmos (Noble USDC) payments using the exact-direct scheme.\n */\n\nimport type {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n} from \"@t402/core/types\";\nimport { SCHEME_EXACT_DIRECT, NOBLE_BECH32_PREFIX } from \"../../constants.js\";\nimport { getDefaultToken, getTokenConfig, TOKEN_REGISTRY } from \"../../tokens.js\";\nimport { normalizeNetwork, toAtomicUnits } from \"../../utils.js\";\n\n/**\n * Configuration options for ExactDirectCosmosServer\n */\nexport interface ExactDirectCosmosServerConfig {\n /** Preferred token symbol (e.g., \"USDC\"). Defaults to network's highest priority token. */\n preferredToken?: string;\n}\n\n/**\n * Cosmos server implementation for the Exact-Direct payment scheme.\n * Handles price parsing and converts user-friendly amounts to token amounts.\n */\nexport class ExactDirectCosmosServer implements SchemeNetworkServer {\n readonly scheme = SCHEME_EXACT_DIRECT;\n private moneyParsers: MoneyParser[] = [];\n private config: ExactDirectCosmosServerConfig;\n\n constructor(config: ExactDirectCosmosServerConfig = {}) {\n this.config = config;\n }\n\n /**\n * Register a custom money parser in the parser chain.\n * Multiple parsers can be registered - they will be tried in registration order.\n * Each parser receives a decimal amount (e.g., 1.50 for $1.50).\n * If a parser returns null, the next parser in the chain will be tried.\n * The default parser is always the final fallback.\n *\n * @param parser - Custom function to convert amount to AssetAmount (or null to skip)\n * @returns The server instance for chaining\n */\n registerMoneyParser(parser: MoneyParser): ExactDirectCosmosServer {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Parses a price into an asset amount.\n * If price is already an AssetAmount, returns it directly.\n * If price is Money (string | number), parses to decimal and tries custom parsers.\n * Falls back to default conversion if all custom parsers return null.\n *\n * @param price - The price to parse\n * @param network - The network to use\n * @returns Promise that resolves to the parsed asset amount\n */\n async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n // Normalize network to CAIP-2 format\n const normalizedNetwork = normalizeNetwork(network);\n\n // If already an AssetAmount, return it directly\n if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n if (!price.asset) {\n throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n }\n return {\n amount: price.amount,\n asset: price.asset,\n extra: price.extra || {},\n };\n }\n\n // Parse Money to decimal number\n const amount = this.parseMoneyToDecimal(price);\n\n // Try each custom money parser in order\n for (const parser of this.moneyParsers) {\n const result = await parser(amount, normalizedNetwork);\n if (result !== null) {\n return result;\n }\n }\n\n // All custom parsers returned null, use default conversion\n return this.defaultMoneyConversion(amount, normalizedNetwork);\n }\n\n /**\n * Build payment requirements for this scheme/network combination.\n *\n * @param paymentRequirements - Base payment requirements with amount/asset already set\n * @param supportedKind - The supported kind from facilitator's /supported endpoint\n * @param extensionKeys - Extensions supported by the facilitator\n * @returns Enhanced payment requirements ready to be sent to clients\n */\n async enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n t402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n extensionKeys: string[],\n ): Promise<PaymentRequirements> {\n // Mark unused parameters to satisfy linter\n void extensionKeys;\n\n // Start with existing extra fields\n const extra = { ...paymentRequirements.extra };\n\n // Add Cosmos-specific extra fields\n const normalizedNetwork = normalizeNetwork(paymentRequirements.network);\n const token = getDefaultToken(normalizedNetwork);\n\n if (token) {\n extra.bech32Prefix = NOBLE_BECH32_PREFIX;\n extra.denom = token.denom;\n }\n\n // Add any facilitator-provided extra fields\n if (supportedKind.extra?.assetSymbol) {\n extra.assetSymbol = supportedKind.extra.assetSymbol;\n }\n if (supportedKind.extra?.assetDecimals) {\n extra.assetDecimals = supportedKind.extra.assetDecimals;\n }\n if (supportedKind.extra?.assetDenom) {\n extra.assetDenom = supportedKind.extra.assetDenom;\n }\n\n return {\n ...paymentRequirements,\n extra,\n };\n }\n\n /**\n * Parse Money (string | number) to a decimal number.\n * Handles formats like \"$1.50\", \"1.50\", 1.50, etc.\n */\n private parseMoneyToDecimal(money: string | number): number {\n if (typeof money === \"number\") {\n return money;\n }\n\n // Remove $ sign and whitespace, then parse\n const cleanMoney = money.replace(/^\\$/, \"\").trim();\n const amount = parseFloat(cleanMoney);\n\n if (isNaN(amount)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n return amount;\n }\n\n /**\n * Default money conversion implementation.\n * Converts decimal amount to the preferred token on the specified network.\n */\n private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n const token = this.getDefaultAsset(network);\n\n // Convert decimal amount to token amount\n const tokenAmount = toAtomicUnits(amount, token.decimals);\n\n return {\n amount: tokenAmount.toString(),\n asset: token.denom,\n extra: {\n symbol: token.symbol,\n name: token.name,\n decimals: token.decimals,\n },\n };\n }\n\n /**\n * Get the default asset info for a network.\n * Priority: configured preferredToken > network default\n */\n private getDefaultAsset(network: Network): {\n denom: string;\n symbol: string;\n name: string;\n decimals: number;\n } {\n // If a preferred token is configured, try to use it\n if (this.config.preferredToken) {\n const preferred = getTokenConfig(network, this.config.preferredToken);\n if (preferred) return preferred;\n }\n\n // Use the network's default token (sorted by priority)\n const defaultToken = getDefaultToken(network);\n if (defaultToken) return defaultToken;\n\n throw new Error(`No tokens configured for network ${network}`);\n }\n\n /**\n * Get all supported networks\n */\n static getSupportedNetworks(): string[] {\n return Object.keys(TOKEN_REGISTRY);\n }\n\n /**\n * Check if a network is supported\n */\n static isNetworkSupported(network: string): boolean {\n return network in TOKEN_REGISTRY;\n }\n}\n","/**\n * Cosmos Facilitator Scheme Implementation - Exact Direct\n *\n * Verifies and settles Cosmos (Noble USDC) payments using the exact-direct scheme.\n * The facilitator verifies that the client's transaction was successful\n * and matches the payment requirements.\n */\n\nimport type {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport type { FacilitatorCosmosSigner, ExactDirectCosmosPayload, MsgSend } from \"../../types.js\";\nimport {\n SCHEME_EXACT_DIRECT,\n COSMOS_CAIP2_NAMESPACE,\n MAX_TRANSACTION_AGE,\n MSG_TYPE_SEND,\n} from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\nimport { getDefaultToken } from \"../../tokens.js\";\n\n/**\n * Configuration for ExactDirectCosmosFacilitator\n */\nexport interface ExactDirectCosmosFacilitatorConfig {\n /** Maximum age of a transaction to accept (in milliseconds) */\n maxTransactionAge?: number;\n /** Duration to cache used transaction hashes (in milliseconds) */\n usedTxCacheDuration?: number;\n}\n\n/**\n * Cosmos facilitator implementation for the Exact-Direct payment scheme.\n * Verifies transaction proofs and confirms payments.\n */\nexport class ExactDirectCosmosFacilitator implements SchemeNetworkFacilitator {\n readonly scheme = SCHEME_EXACT_DIRECT;\n readonly caipFamily = `${COSMOS_CAIP2_NAMESPACE}:*`;\n\n private readonly config: Required<ExactDirectCosmosFacilitatorConfig>;\n private usedTxs: Map<string, number> = new Map();\n\n constructor(\n private readonly signer: FacilitatorCosmosSigner,\n config?: ExactDirectCosmosFacilitatorConfig,\n ) {\n this.config = {\n maxTransactionAge: config?.maxTransactionAge ?? MAX_TRANSACTION_AGE,\n usedTxCacheDuration: config?.usedTxCacheDuration ?? 24 * 60 * 60 * 1000, // 24 hours\n };\n\n // Start cleanup interval\n this.startCleanupInterval();\n }\n\n /**\n * Get extra data for a supported kind\n */\n getExtra(network: Network): Record<string, unknown> | undefined {\n const token = getDefaultToken(network);\n if (!token) {\n return undefined;\n }\n return {\n assetSymbol: token.symbol,\n assetDecimals: token.decimals,\n assetDenom: token.denom,\n };\n }\n\n /**\n * Get signer addresses for a network\n */\n getSigners(network: Network): string[] {\n return this.signer.getAddresses(network);\n }\n\n /**\n * Verify a payment payload\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const network = normalizeNetwork(requirements.network);\n\n // Validate scheme\n if (payload.accepted.scheme !== SCHEME_EXACT_DIRECT) {\n return {\n isValid: false,\n invalidReason: \"invalid_scheme\",\n };\n }\n\n // Validate network\n if (normalizeNetwork(payload.accepted.network) !== network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n };\n }\n\n // Parse payload\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n if (!cosmosPayload.txHash) {\n return {\n isValid: false,\n invalidReason: \"missing_tx_hash\",\n };\n }\n if (!cosmosPayload.from || !isValidAddress(cosmosPayload.from)) {\n return {\n isValid: false,\n invalidReason: \"invalid_from_address\",\n };\n }\n\n // Check for replay attack\n if (this.isTxUsed(cosmosPayload.txHash)) {\n return {\n isValid: false,\n invalidReason: \"transaction_already_used\",\n payer: cosmosPayload.from,\n };\n }\n\n try {\n // Query the transaction\n const tx = await this.signer.queryTransaction(network, cosmosPayload.txHash);\n\n // Check transaction succeeded (code 0 = success)\n if (tx.code !== 0) {\n return {\n isValid: false,\n invalidReason: \"transaction_failed\",\n payer: cosmosPayload.from,\n };\n }\n\n // Find the MsgSend in the transaction messages\n const msgSend = this.findMsgSend(tx.tx.body.messages);\n if (!msgSend) {\n return {\n isValid: false,\n invalidReason: \"no_msg_send_found\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify recipient\n if (msgSend.toAddress !== requirements.payTo) {\n return {\n isValid: false,\n invalidReason: \"wrong_recipient\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify sender matches payload\n if (msgSend.fromAddress !== cosmosPayload.from) {\n return {\n isValid: false,\n invalidReason: \"sender_mismatch\",\n payer: cosmosPayload.from,\n };\n }\n\n // Determine expected denom\n const expectedDenom = (requirements.extra?.denom as string) || requirements.asset;\n\n // Verify amount and denomination\n const coin = this.getAmountByDenom(msgSend, expectedDenom);\n if (!coin) {\n return {\n isValid: false,\n invalidReason: \"wrong_denomination\",\n payer: cosmosPayload.from,\n };\n }\n\n const txAmount = BigInt(coin.amount);\n const requiredAmount = BigInt(requirements.amount);\n if (txAmount < requiredAmount) {\n return {\n isValid: false,\n invalidReason: \"insufficient_amount\",\n payer: cosmosPayload.from,\n };\n }\n\n // Mark transaction as used\n this.markTxUsed(cosmosPayload.txHash);\n\n return {\n isValid: true,\n payer: cosmosPayload.from,\n };\n } catch {\n return {\n isValid: false,\n invalidReason: \"transaction_not_found\",\n payer: cosmosPayload.from,\n };\n }\n }\n\n /**\n * Settle a payment - for exact-direct, the transfer is already complete\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n // Verify first\n const verifyResult = await this.verify(payload, requirements);\n if (!verifyResult.isValid) {\n return {\n success: false,\n errorReason: verifyResult.invalidReason || \"verification_failed\",\n payer: verifyResult.payer,\n transaction: \"\",\n network: normalizeNetwork(requirements.network),\n };\n }\n\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n\n // For exact-direct, settlement is already complete\n return {\n success: true,\n transaction: cosmosPayload.txHash,\n network: normalizeNetwork(requirements.network),\n payer: cosmosPayload.from,\n };\n }\n\n /**\n * Find a MsgSend in transaction messages\n */\n private findMsgSend(messages: MsgSend[]): MsgSend | null {\n for (const msg of messages) {\n if (msg[\"@type\"] === MSG_TYPE_SEND || (!msg[\"@type\"] && msg.fromAddress && msg.toAddress)) {\n return msg;\n }\n }\n return null;\n }\n\n /**\n * Get a specific coin amount from a MsgSend by denomination\n */\n private getAmountByDenom(msg: MsgSend, denom: string): { denom: string; amount: string } | null {\n for (const coin of msg.amount) {\n if (coin.denom === denom) {\n return coin;\n }\n }\n return null;\n }\n\n /**\n * Check if a transaction has been used\n */\n private isTxUsed(txHash: string): boolean {\n return this.usedTxs.has(txHash);\n }\n\n /**\n * Mark a transaction as used\n */\n private markTxUsed(txHash: string): void {\n this.usedTxs.set(txHash, Date.now());\n }\n\n /**\n * Start the cleanup interval for used transactions\n */\n private startCleanupInterval(): void {\n setInterval(\n () => {\n const cutoff = Date.now() - this.config.usedTxCacheDuration;\n for (const [txHash, usedAt] of this.usedTxs.entries()) {\n if (usedAt < cutoff) {\n this.usedTxs.delete(txHash);\n }\n }\n },\n 60 * 60 * 1000,\n ); // Cleanup every hour\n }\n}\n"],"mappings":"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","names":[]}
@@ -152,4 +152,4 @@ interface FacilitatorCosmosSigner {
152
152
  getBalance(network: string, address: string, denom: string): Promise<bigint>;
153
153
  }
154
154
 
155
- export type { Coin as C, ExactDirectCosmosPayload as E, FacilitatorCosmosSigner as F, MsgSend as M, NetworkConfig as N, TokenConfig as T, TransactionResult as a, TxWrapper as b, TxBody as c, ClientCosmosSigner as d };
155
+ export type { ClientCosmosSigner as C, ExactDirectCosmosPayload as E, FacilitatorCosmosSigner as F, MsgSend as M, NetworkConfig as N, TokenConfig as T, Coin as a, TransactionResult as b, TxBody as c, TxWrapper as d };
@@ -220,4 +220,4 @@ var ExactDirectCosmosFacilitator = class {
220
220
  export {
221
221
  ExactDirectCosmosFacilitator
222
222
  };
223
- //# sourceMappingURL=chunk-XUMAS5DJ.mjs.map
223
+ //# sourceMappingURL=chunk-F7HRSYNO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/exact-direct/facilitator/scheme.ts"],"sourcesContent":["/**\n * Cosmos Facilitator Scheme Implementation - Exact Direct\n *\n * Verifies and settles Cosmos (Noble USDC) payments using the exact-direct scheme.\n * The facilitator verifies that the client's transaction was successful\n * and matches the payment requirements.\n */\n\nimport type {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport type { FacilitatorCosmosSigner, ExactDirectCosmosPayload, MsgSend } from \"../../types.js\";\nimport {\n SCHEME_EXACT_DIRECT,\n COSMOS_CAIP2_NAMESPACE,\n MAX_TRANSACTION_AGE,\n MSG_TYPE_SEND,\n} from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\nimport { getDefaultToken } from \"../../tokens.js\";\n\n/**\n * Configuration for ExactDirectCosmosFacilitator\n */\nexport interface ExactDirectCosmosFacilitatorConfig {\n /** Maximum age of a transaction to accept (in milliseconds) */\n maxTransactionAge?: number;\n /** Duration to cache used transaction hashes (in milliseconds) */\n usedTxCacheDuration?: number;\n}\n\n/**\n * Cosmos facilitator implementation for the Exact-Direct payment scheme.\n * Verifies transaction proofs and confirms payments.\n */\nexport class ExactDirectCosmosFacilitator implements SchemeNetworkFacilitator {\n readonly scheme = SCHEME_EXACT_DIRECT;\n readonly caipFamily = `${COSMOS_CAIP2_NAMESPACE}:*`;\n\n private readonly config: Required<ExactDirectCosmosFacilitatorConfig>;\n private usedTxs: Map<string, number> = new Map();\n\n constructor(\n private readonly signer: FacilitatorCosmosSigner,\n config?: ExactDirectCosmosFacilitatorConfig,\n ) {\n this.config = {\n maxTransactionAge: config?.maxTransactionAge ?? MAX_TRANSACTION_AGE,\n usedTxCacheDuration: config?.usedTxCacheDuration ?? 24 * 60 * 60 * 1000, // 24 hours\n };\n\n // Start cleanup interval\n this.startCleanupInterval();\n }\n\n /**\n * Get extra data for a supported kind\n */\n getExtra(network: Network): Record<string, unknown> | undefined {\n const token = getDefaultToken(network);\n if (!token) {\n return undefined;\n }\n return {\n assetSymbol: token.symbol,\n assetDecimals: token.decimals,\n assetDenom: token.denom,\n };\n }\n\n /**\n * Get signer addresses for a network\n */\n getSigners(network: Network): string[] {\n return this.signer.getAddresses(network);\n }\n\n /**\n * Verify a payment payload\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const network = normalizeNetwork(requirements.network);\n\n // Validate scheme\n if (payload.accepted.scheme !== SCHEME_EXACT_DIRECT) {\n return {\n isValid: false,\n invalidReason: \"invalid_scheme\",\n };\n }\n\n // Validate network\n if (normalizeNetwork(payload.accepted.network) !== network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n };\n }\n\n // Parse payload\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n if (!cosmosPayload.txHash) {\n return {\n isValid: false,\n invalidReason: \"missing_tx_hash\",\n };\n }\n if (!cosmosPayload.from || !isValidAddress(cosmosPayload.from)) {\n return {\n isValid: false,\n invalidReason: \"invalid_from_address\",\n };\n }\n\n // Check for replay attack\n if (this.isTxUsed(cosmosPayload.txHash)) {\n return {\n isValid: false,\n invalidReason: \"transaction_already_used\",\n payer: cosmosPayload.from,\n };\n }\n\n try {\n // Query the transaction\n const tx = await this.signer.queryTransaction(network, cosmosPayload.txHash);\n\n // Check transaction succeeded (code 0 = success)\n if (tx.code !== 0) {\n return {\n isValid: false,\n invalidReason: \"transaction_failed\",\n payer: cosmosPayload.from,\n };\n }\n\n // Find the MsgSend in the transaction messages\n const msgSend = this.findMsgSend(tx.tx.body.messages);\n if (!msgSend) {\n return {\n isValid: false,\n invalidReason: \"no_msg_send_found\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify recipient\n if (msgSend.toAddress !== requirements.payTo) {\n return {\n isValid: false,\n invalidReason: \"wrong_recipient\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify sender matches payload\n if (msgSend.fromAddress !== cosmosPayload.from) {\n return {\n isValid: false,\n invalidReason: \"sender_mismatch\",\n payer: cosmosPayload.from,\n };\n }\n\n // Determine expected denom\n const expectedDenom = (requirements.extra?.denom as string) || requirements.asset;\n\n // Verify amount and denomination\n const coin = this.getAmountByDenom(msgSend, expectedDenom);\n if (!coin) {\n return {\n isValid: false,\n invalidReason: \"wrong_denomination\",\n payer: cosmosPayload.from,\n };\n }\n\n const txAmount = BigInt(coin.amount);\n const requiredAmount = BigInt(requirements.amount);\n if (txAmount < requiredAmount) {\n return {\n isValid: false,\n invalidReason: \"insufficient_amount\",\n payer: cosmosPayload.from,\n };\n }\n\n // Mark transaction as used\n this.markTxUsed(cosmosPayload.txHash);\n\n return {\n isValid: true,\n payer: cosmosPayload.from,\n };\n } catch {\n return {\n isValid: false,\n invalidReason: \"transaction_not_found\",\n payer: cosmosPayload.from,\n };\n }\n }\n\n /**\n * Settle a payment - for exact-direct, the transfer is already complete\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n // Verify first\n const verifyResult = await this.verify(payload, requirements);\n if (!verifyResult.isValid) {\n return {\n success: false,\n errorReason: verifyResult.invalidReason || \"verification_failed\",\n payer: verifyResult.payer,\n transaction: \"\",\n network: normalizeNetwork(requirements.network),\n };\n }\n\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n\n // For exact-direct, settlement is already complete\n return {\n success: true,\n transaction: cosmosPayload.txHash,\n network: normalizeNetwork(requirements.network),\n payer: cosmosPayload.from,\n };\n }\n\n /**\n * Find a MsgSend in transaction messages\n */\n private findMsgSend(messages: MsgSend[]): MsgSend | null {\n for (const msg of messages) {\n if (msg[\"@type\"] === MSG_TYPE_SEND || (!msg[\"@type\"] && msg.fromAddress && msg.toAddress)) {\n return msg;\n }\n }\n return null;\n }\n\n /**\n * Get a specific coin amount from a MsgSend by denomination\n */\n private getAmountByDenom(msg: MsgSend, denom: string): { denom: string; amount: string } | null {\n for (const coin of msg.amount) {\n if (coin.denom === denom) {\n return coin;\n }\n }\n return null;\n }\n\n /**\n * Check if a transaction has been used\n */\n private isTxUsed(txHash: string): boolean {\n return this.usedTxs.has(txHash);\n }\n\n /**\n * Mark a transaction as used\n */\n private markTxUsed(txHash: string): void {\n this.usedTxs.set(txHash, Date.now());\n }\n\n /**\n * Start the cleanup interval for used transactions\n */\n private startCleanupInterval(): void {\n setInterval(\n () => {\n const cutoff = Date.now() - this.config.usedTxCacheDuration;\n for (const [txHash, usedAt] of this.usedTxs.entries()) {\n if (usedAt < cutoff) {\n this.usedTxs.delete(txHash);\n }\n }\n },\n 60 * 60 * 1000,\n ); // Cleanup every hour\n }\n}\n"],"mappings":"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","names":[]}
@@ -65,4 +65,4 @@ var ExactDirectCosmosClient = class {
65
65
  export {
66
66
  ExactDirectCosmosClient
67
67
  };
68
- //# sourceMappingURL=chunk-QP5VO3IO.mjs.map
68
+ //# sourceMappingURL=chunk-ZWWMTJH5.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/exact-direct/client/scheme.ts"],"sourcesContent":["/**\n * Cosmos Client Scheme Implementation - Exact Direct\n *\n * Creates payment payloads for Cosmos MsgSend transfers using the exact-direct scheme.\n * In this scheme, the client executes the bank send directly and provides\n * the transaction hash as proof of payment.\n */\n\nimport type { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport type { ClientCosmosSigner, ExactDirectCosmosPayload } from \"../../types.js\";\nimport { SCHEME_EXACT_DIRECT, USDC_DENOM } from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\n\n/**\n * Configuration for ExactDirectCosmosClient\n */\nexport interface ExactDirectCosmosClientConfig {\n /** Override the default denomination */\n denom?: string;\n}\n\n/**\n * Cosmos client implementation for the Exact-Direct payment scheme.\n *\n * Executes a Cosmos MsgSend and returns the transaction hash as proof.\n */\nexport class ExactDirectCosmosClient implements SchemeNetworkClient {\n readonly scheme = SCHEME_EXACT_DIRECT;\n\n /**\n * Creates a new ExactDirectCosmosClient instance.\n *\n * @param signer - The Cosmos signer for client operations\n * @param config - Optional configuration overrides\n */\n constructor(\n private readonly signer: ClientCosmosSigner,\n private readonly config: ExactDirectCosmosClientConfig = {},\n ) {}\n\n /**\n * Creates a payment payload by executing the transfer.\n *\n * Unlike other schemes where the client creates a signed message for\n * the facilitator to execute, the exact-direct scheme has the client\n * execute the transfer directly. The transaction hash is then used\n * as proof of payment.\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload with transaction hash\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Normalize and validate network\n const network = normalizeNetwork(paymentRequirements.network);\n\n // Validate required fields\n if (!paymentRequirements.payTo) {\n throw new Error(\"PayTo address is required\");\n }\n if (!paymentRequirements.amount) {\n throw new Error(\"Amount is required\");\n }\n\n // Validate addresses\n if (!isValidAddress(paymentRequirements.payTo)) {\n throw new Error(`Invalid recipient address: ${paymentRequirements.payTo}`);\n }\n if (!isValidAddress(this.signer.address)) {\n throw new Error(`Invalid sender address: ${this.signer.address}`);\n }\n\n const recipient = paymentRequirements.payTo;\n const amount = paymentRequirements.amount;\n\n // Determine denomination from extra field, config, or default\n const denom =\n (paymentRequirements.extra?.denom as string) || this.config.denom || USDC_DENOM;\n\n // Execute the transfer\n const txHash = await this.signer.sendTokens(network, recipient, amount, denom);\n\n // Build the payload\n const payload: ExactDirectCosmosPayload = {\n txHash,\n from: this.signer.address,\n to: recipient,\n amount: amount,\n denom,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n}\n"],"mappings":";;;;;;;;AA0BO,IAAM,0BAAN,MAA6D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlE,YACmB,QACA,SAAwC,CAAC,GAC1D;AAFiB;AACA;AAVnB,SAAS,SAAS;AAAA,EAWf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcH,MAAM,qBACJ,aACA,qBAC0D;AAE1D,UAAM,UAAU,iBAAiB,oBAAoB,OAAO;AAG5D,QAAI,CAAC,oBAAoB,OAAO;AAC9B,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,QAAI,CAAC,oBAAoB,QAAQ;AAC/B,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AAGA,QAAI,CAAC,eAAe,oBAAoB,KAAK,GAAG;AAC9C,YAAM,IAAI,MAAM,8BAA8B,oBAAoB,KAAK,EAAE;AAAA,IAC3E;AACA,QAAI,CAAC,eAAe,KAAK,OAAO,OAAO,GAAG;AACxC,YAAM,IAAI,MAAM,2BAA2B,KAAK,OAAO,OAAO,EAAE;AAAA,IAClE;AAEA,UAAM,YAAY,oBAAoB;AACtC,UAAM,SAAS,oBAAoB;AAGnC,UAAM,QACH,oBAAoB,OAAO,SAAoB,KAAK,OAAO,SAAS;AAGvE,UAAM,SAAS,MAAM,KAAK,OAAO,WAAW,SAAS,WAAW,QAAQ,KAAK;AAG7E,UAAM,UAAoC;AAAA,MACxC;AAAA,MACA,MAAM,KAAK,OAAO;AAAA,MAClB,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/exact-direct/client/scheme.ts"],"sourcesContent":["/**\n * Cosmos Client Scheme Implementation - Exact Direct\n *\n * Creates payment payloads for Cosmos MsgSend transfers using the exact-direct scheme.\n * In this scheme, the client executes the bank send directly and provides\n * the transaction hash as proof of payment.\n */\n\nimport type { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport type { ClientCosmosSigner, ExactDirectCosmosPayload } from \"../../types.js\";\nimport { SCHEME_EXACT_DIRECT, USDC_DENOM } from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\n\n/**\n * Configuration for ExactDirectCosmosClient\n */\nexport interface ExactDirectCosmosClientConfig {\n /** Override the default denomination */\n denom?: string;\n}\n\n/**\n * Cosmos client implementation for the Exact-Direct payment scheme.\n *\n * Executes a Cosmos MsgSend and returns the transaction hash as proof.\n */\nexport class ExactDirectCosmosClient implements SchemeNetworkClient {\n readonly scheme = SCHEME_EXACT_DIRECT;\n\n /**\n * Creates a new ExactDirectCosmosClient instance.\n *\n * @param signer - The Cosmos signer for client operations\n * @param config - Optional configuration overrides\n */\n constructor(\n private readonly signer: ClientCosmosSigner,\n private readonly config: ExactDirectCosmosClientConfig = {},\n ) {}\n\n /**\n * Creates a payment payload by executing the transfer.\n *\n * Unlike other schemes where the client creates a signed message for\n * the facilitator to execute, the exact-direct scheme has the client\n * execute the transfer directly. The transaction hash is then used\n * as proof of payment.\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload with transaction hash\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Normalize and validate network\n const network = normalizeNetwork(paymentRequirements.network);\n\n // Validate required fields\n if (!paymentRequirements.payTo) {\n throw new Error(\"PayTo address is required\");\n }\n if (!paymentRequirements.amount) {\n throw new Error(\"Amount is required\");\n }\n\n // Validate addresses\n if (!isValidAddress(paymentRequirements.payTo)) {\n throw new Error(`Invalid recipient address: ${paymentRequirements.payTo}`);\n }\n if (!isValidAddress(this.signer.address)) {\n throw new Error(`Invalid sender address: ${this.signer.address}`);\n }\n\n const recipient = paymentRequirements.payTo;\n const amount = paymentRequirements.amount;\n\n // Determine denomination from extra field, config, or default\n const denom = (paymentRequirements.extra?.denom as string) || this.config.denom || USDC_DENOM;\n\n // Execute the transfer\n const txHash = await this.signer.sendTokens(network, recipient, amount, denom);\n\n // Build the payload\n const payload: ExactDirectCosmosPayload = {\n txHash,\n from: this.signer.address,\n to: recipient,\n amount: amount,\n denom,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n}\n"],"mappings":";;;;;;;;AA0BO,IAAM,0BAAN,MAA6D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlE,YACmB,QACA,SAAwC,CAAC,GAC1D;AAFiB;AACA;AAVnB,SAAS,SAAS;AAAA,EAWf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcH,MAAM,qBACJ,aACA,qBAC0D;AAE1D,UAAM,UAAU,iBAAiB,oBAAoB,OAAO;AAG5D,QAAI,CAAC,oBAAoB,OAAO;AAC9B,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,QAAI,CAAC,oBAAoB,QAAQ;AAC/B,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AAGA,QAAI,CAAC,eAAe,oBAAoB,KAAK,GAAG;AAC9C,YAAM,IAAI,MAAM,8BAA8B,oBAAoB,KAAK,EAAE;AAAA,IAC3E;AACA,QAAI,CAAC,eAAe,KAAK,OAAO,OAAO,GAAG;AACxC,YAAM,IAAI,MAAM,2BAA2B,KAAK,OAAO,OAAO,EAAE;AAAA,IAClE;AAEA,UAAM,YAAY,oBAAoB;AACtC,UAAM,SAAS,oBAAoB;AAGnC,UAAM,QAAS,oBAAoB,OAAO,SAAoB,KAAK,OAAO,SAAS;AAGnF,UAAM,SAAS,MAAM,KAAK,OAAO,WAAW,SAAS,WAAW,QAAQ,KAAK;AAG7E,UAAM,UAAoC;AAAA,MACxC;AAAA,MACA,MAAM,KAAK,OAAO;AAAA,MAClB,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -1,5 +1,5 @@
1
1
  import { SchemeNetworkClient, PaymentRequirements, PaymentPayload } from '@t402/core/types';
2
- import { d as ClientCosmosSigner } from '../../types-CgseoctH.mjs';
2
+ import { C as ClientCosmosSigner } from '../../types-27CIV52j.mjs';
3
3
 
4
4
  /**
5
5
  * Cosmos Client Scheme Implementation - Exact Direct
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ExactDirectCosmosClient
3
- } from "../../chunk-QP5VO3IO.mjs";
3
+ } from "../../chunk-ZWWMTJH5.mjs";
4
4
  import "../../chunk-2UTEGIZ2.mjs";
5
5
  export {
6
6
  ExactDirectCosmosClient
@@ -1,5 +1,5 @@
1
1
  import { SchemeNetworkFacilitator, Network, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse } from '@t402/core/types';
2
- import { F as FacilitatorCosmosSigner } from '../../types-CgseoctH.mjs';
2
+ import { F as FacilitatorCosmosSigner } from '../../types-27CIV52j.mjs';
3
3
 
4
4
  /**
5
5
  * Cosmos Facilitator Scheme Implementation - Exact Direct
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ExactDirectCosmosFacilitator
3
- } from "../../chunk-XUMAS5DJ.mjs";
3
+ } from "../../chunk-F7HRSYNO.mjs";
4
4
  import "../../chunk-57DBLYIR.mjs";
5
5
  import "../../chunk-2UTEGIZ2.mjs";
6
6
  export {
@@ -1,5 +1,5 @@
1
- import { T as TokenConfig } from './types-CgseoctH.mjs';
2
- export { d as ClientCosmosSigner, C as Coin, E as ExactDirectCosmosPayload, F as FacilitatorCosmosSigner, M as MsgSend, N as NetworkConfig, a as TransactionResult, c as TxBody, b as TxWrapper } from './types-CgseoctH.mjs';
1
+ import { T as TokenConfig } from './types-27CIV52j.mjs';
2
+ export { C as ClientCosmosSigner, a as Coin, E as ExactDirectCosmosPayload, F as FacilitatorCosmosSigner, M as MsgSend, N as NetworkConfig, b as TransactionResult, c as TxBody, d as TxWrapper } from './types-27CIV52j.mjs';
3
3
  export { ExactDirectCosmosClient, ExactDirectCosmosClientConfig } from './exact-direct/client/index.mjs';
4
4
  export { ExactDirectCosmosServer, ExactDirectCosmosServerConfig } from './exact-direct/server/index.mjs';
5
5
  export { ExactDirectCosmosFacilitator, ExactDirectCosmosFacilitatorConfig } from './exact-direct/facilitator/index.mjs';
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  ExactDirectCosmosClient
3
- } from "./chunk-QP5VO3IO.mjs";
3
+ } from "./chunk-ZWWMTJH5.mjs";
4
4
  import {
5
5
  ExactDirectCosmosServer
6
6
  } from "./chunk-JV6LXL2U.mjs";
7
7
  import {
8
8
  ExactDirectCosmosFacilitator
9
- } from "./chunk-XUMAS5DJ.mjs";
9
+ } from "./chunk-F7HRSYNO.mjs";
10
10
  import {
11
11
  TOKEN_REGISTRY,
12
12
  getDefaultToken,
@@ -152,4 +152,4 @@ interface FacilitatorCosmosSigner {
152
152
  getBalance(network: string, address: string, denom: string): Promise<bigint>;
153
153
  }
154
154
 
155
- export type { Coin as C, ExactDirectCosmosPayload as E, FacilitatorCosmosSigner as F, MsgSend as M, NetworkConfig as N, TokenConfig as T, TransactionResult as a, TxWrapper as b, TxBody as c, ClientCosmosSigner as d };
155
+ export type { ClientCosmosSigner as C, ExactDirectCosmosPayload as E, FacilitatorCosmosSigner as F, MsgSend as M, NetworkConfig as N, TokenConfig as T, Coin as a, TransactionResult as b, TxBody as c, TxWrapper as d };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t402/cosmos",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "main": "./dist/cjs/index.js",
5
5
  "module": "./dist/esm/index.js",
6
6
  "types": "./dist/cjs/index.d.ts",
@@ -14,28 +14,32 @@
14
14
  ],
15
15
  "license": "Apache-2.0",
16
16
  "author": "T402 Team",
17
- "repository": "https://github.com/t402-io/t402",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/t402-io/t402.git",
20
+ "directory": "sdks/typescript/packages/mechanisms/cosmos"
21
+ },
18
22
  "description": "t402 Payment Protocol Cosmos (Noble USDC) Implementation",
19
23
  "devDependencies": {
20
- "@eslint/js": "^9.24.0",
21
- "@types/node": "^25.2.0",
22
- "@typescript-eslint/eslint-plugin": "^8.29.1",
23
- "@typescript-eslint/parser": "^8.29.1",
24
+ "@eslint/js": "^9.39.2",
25
+ "@types/node": "^25.2.3",
26
+ "@typescript-eslint/eslint-plugin": "^8.56.0",
27
+ "@typescript-eslint/parser": "^8.56.0",
24
28
  "eslint": "^9.24.0",
25
29
  "eslint-plugin-import": "^2.31.0",
26
- "eslint-plugin-jsdoc": "^62.5.0",
27
- "eslint-plugin-prettier": "^5.2.6",
28
- "glob": "^13.0.0",
29
- "prettier": "3.5.2",
30
- "tsup": "^8.4.0",
30
+ "eslint-plugin-jsdoc": "^62.6.0",
31
+ "eslint-plugin-prettier": "^5.5.5",
32
+ "glob": "^13.0.5",
33
+ "prettier": "3.8.1",
34
+ "tsup": "^8.5.1",
31
35
  "tsx": "^4.21.0",
32
- "typescript": "^5.7.3",
36
+ "typescript": "^5.9.3",
33
37
  "vite": "^7.3.1",
34
- "vite-tsconfig-paths": "^5.1.4",
38
+ "vite-tsconfig-paths": "^6.1.1",
35
39
  "vitest": "^3.2.4"
36
40
  },
37
41
  "dependencies": {
38
- "@t402/core": "2.4.0"
42
+ "@t402/core": "2.6.0"
39
43
  },
40
44
  "exports": {
41
45
  ".": {
@@ -82,6 +86,10 @@
82
86
  "files": [
83
87
  "dist"
84
88
  ],
89
+ "homepage": "https://t402.io",
90
+ "publishConfig": {
91
+ "access": "public"
92
+ },
85
93
  "scripts": {
86
94
  "start": "tsx --env-file=.env index.ts",
87
95
  "build": "tsup",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/exact-direct/facilitator/scheme.ts"],"sourcesContent":["/**\n * Cosmos Facilitator Scheme Implementation - Exact Direct\n *\n * Verifies and settles Cosmos (Noble USDC) payments using the exact-direct scheme.\n * The facilitator verifies that the client's transaction was successful\n * and matches the payment requirements.\n */\n\nimport type {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport type { FacilitatorCosmosSigner, ExactDirectCosmosPayload, MsgSend } from \"../../types.js\";\nimport { SCHEME_EXACT_DIRECT, COSMOS_CAIP2_NAMESPACE, MAX_TRANSACTION_AGE, MSG_TYPE_SEND } from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\nimport { getDefaultToken } from \"../../tokens.js\";\n\n/**\n * Configuration for ExactDirectCosmosFacilitator\n */\nexport interface ExactDirectCosmosFacilitatorConfig {\n /** Maximum age of a transaction to accept (in milliseconds) */\n maxTransactionAge?: number;\n /** Duration to cache used transaction hashes (in milliseconds) */\n usedTxCacheDuration?: number;\n}\n\n/**\n * Cosmos facilitator implementation for the Exact-Direct payment scheme.\n * Verifies transaction proofs and confirms payments.\n */\nexport class ExactDirectCosmosFacilitator implements SchemeNetworkFacilitator {\n readonly scheme = SCHEME_EXACT_DIRECT;\n readonly caipFamily = `${COSMOS_CAIP2_NAMESPACE}:*`;\n\n private readonly config: Required<ExactDirectCosmosFacilitatorConfig>;\n private usedTxs: Map<string, number> = new Map();\n\n constructor(\n private readonly signer: FacilitatorCosmosSigner,\n config?: ExactDirectCosmosFacilitatorConfig,\n ) {\n this.config = {\n maxTransactionAge: config?.maxTransactionAge ?? MAX_TRANSACTION_AGE,\n usedTxCacheDuration: config?.usedTxCacheDuration ?? 24 * 60 * 60 * 1000, // 24 hours\n };\n\n // Start cleanup interval\n this.startCleanupInterval();\n }\n\n /**\n * Get extra data for a supported kind\n */\n getExtra(network: Network): Record<string, unknown> | undefined {\n const token = getDefaultToken(network);\n if (!token) {\n return undefined;\n }\n return {\n assetSymbol: token.symbol,\n assetDecimals: token.decimals,\n assetDenom: token.denom,\n };\n }\n\n /**\n * Get signer addresses for a network\n */\n getSigners(network: Network): string[] {\n return this.signer.getAddresses(network);\n }\n\n /**\n * Verify a payment payload\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const network = normalizeNetwork(requirements.network);\n\n // Validate scheme\n if (payload.accepted.scheme !== SCHEME_EXACT_DIRECT) {\n return {\n isValid: false,\n invalidReason: \"invalid_scheme\",\n };\n }\n\n // Validate network\n if (normalizeNetwork(payload.accepted.network) !== network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n };\n }\n\n // Parse payload\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n if (!cosmosPayload.txHash) {\n return {\n isValid: false,\n invalidReason: \"missing_tx_hash\",\n };\n }\n if (!cosmosPayload.from || !isValidAddress(cosmosPayload.from)) {\n return {\n isValid: false,\n invalidReason: \"invalid_from_address\",\n };\n }\n\n // Check for replay attack\n if (this.isTxUsed(cosmosPayload.txHash)) {\n return {\n isValid: false,\n invalidReason: \"transaction_already_used\",\n payer: cosmosPayload.from,\n };\n }\n\n try {\n // Query the transaction\n const tx = await this.signer.queryTransaction(network, cosmosPayload.txHash);\n\n // Check transaction succeeded (code 0 = success)\n if (tx.code !== 0) {\n return {\n isValid: false,\n invalidReason: \"transaction_failed\",\n payer: cosmosPayload.from,\n };\n }\n\n // Find the MsgSend in the transaction messages\n const msgSend = this.findMsgSend(tx.tx.body.messages);\n if (!msgSend) {\n return {\n isValid: false,\n invalidReason: \"no_msg_send_found\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify recipient\n if (msgSend.toAddress !== requirements.payTo) {\n return {\n isValid: false,\n invalidReason: \"wrong_recipient\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify sender matches payload\n if (msgSend.fromAddress !== cosmosPayload.from) {\n return {\n isValid: false,\n invalidReason: \"sender_mismatch\",\n payer: cosmosPayload.from,\n };\n }\n\n // Determine expected denom\n const expectedDenom = (requirements.extra?.denom as string) || requirements.asset;\n\n // Verify amount and denomination\n const coin = this.getAmountByDenom(msgSend, expectedDenom);\n if (!coin) {\n return {\n isValid: false,\n invalidReason: \"wrong_denomination\",\n payer: cosmosPayload.from,\n };\n }\n\n const txAmount = BigInt(coin.amount);\n const requiredAmount = BigInt(requirements.amount);\n if (txAmount < requiredAmount) {\n return {\n isValid: false,\n invalidReason: \"insufficient_amount\",\n payer: cosmosPayload.from,\n };\n }\n\n // Mark transaction as used\n this.markTxUsed(cosmosPayload.txHash);\n\n return {\n isValid: true,\n payer: cosmosPayload.from,\n };\n } catch {\n return {\n isValid: false,\n invalidReason: \"transaction_not_found\",\n payer: cosmosPayload.from,\n };\n }\n }\n\n /**\n * Settle a payment - for exact-direct, the transfer is already complete\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n // Verify first\n const verifyResult = await this.verify(payload, requirements);\n if (!verifyResult.isValid) {\n return {\n success: false,\n errorReason: verifyResult.invalidReason || \"verification_failed\",\n payer: verifyResult.payer,\n transaction: \"\",\n network: normalizeNetwork(requirements.network),\n };\n }\n\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n\n // For exact-direct, settlement is already complete\n return {\n success: true,\n transaction: cosmosPayload.txHash,\n network: normalizeNetwork(requirements.network),\n payer: cosmosPayload.from,\n };\n }\n\n /**\n * Find a MsgSend in transaction messages\n */\n private findMsgSend(messages: MsgSend[]): MsgSend | null {\n for (const msg of messages) {\n if (msg[\"@type\"] === MSG_TYPE_SEND || (!msg[\"@type\"] && msg.fromAddress && msg.toAddress)) {\n return msg;\n }\n }\n return null;\n }\n\n /**\n * Get a specific coin amount from a MsgSend by denomination\n */\n private getAmountByDenom(msg: MsgSend, denom: string): { denom: string; amount: string } | null {\n for (const coin of msg.amount) {\n if (coin.denom === denom) {\n return coin;\n }\n }\n return null;\n }\n\n /**\n * Check if a transaction has been used\n */\n private isTxUsed(txHash: string): boolean {\n return this.usedTxs.has(txHash);\n }\n\n /**\n * Mark a transaction as used\n */\n private markTxUsed(txHash: string): void {\n this.usedTxs.set(txHash, Date.now());\n }\n\n /**\n * Start the cleanup interval for used transactions\n */\n private startCleanupInterval(): void {\n setInterval(\n () => {\n const cutoff = Date.now() - this.config.usedTxCacheDuration;\n for (const [txHash, usedAt] of this.usedTxs.entries()) {\n if (usedAt < cutoff) {\n this.usedTxs.delete(txHash);\n }\n }\n },\n 60 * 60 * 1000,\n ); // Cleanup every hour\n }\n}\n"],"mappings":"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","names":[]}