diff --git a/Dockerfile b/Dockerfile index 9aabeb3..a4bafa1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,15 @@ +FROM node:22-alpine AS builder +WORKDIR /app +COPY package*.json ./ +RUN npm ci +COPY tsup.config* tsconfig* ./ +COPY src/ ./src/ +RUN npm run build + FROM node:22-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --omit=dev -COPY build/ ./build/ +COPY --from=builder /app/build/ ./build/ EXPOSE 3000 CMD ["node", "build/index.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c48d825 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +services: + vector-mcp: + build: . + container_name: vector-mcp + restart: unless-stopped + ports: + - "127.0.0.1:3000:3000" + environment: + - VECTOR_OGMIOS_URL=https://ogmios.vector.testnet.apexfusion.org + - VECTOR_KOIOS_URL=https://v2.koios.vector.testnet.apexfusion.org/ + - VECTOR_SUBMIT_URL=https://submit.vector.testnet.apexfusion.org/api/submit/tx + - VECTOR_EXPLORER_URL=https://vector.testnet.apexscan.org diff --git a/src/vector/ogmios-provider.ts b/src/vector/ogmios-provider.ts index 7a1f25e..7565a77 100644 --- a/src/vector/ogmios-provider.ts +++ b/src/vector/ogmios-provider.ts @@ -64,30 +64,39 @@ export class OgmiosProvider implements Provider { async getProtocolParameters(): Promise { const result = await this.rpc('queryLedgerState/protocolParameters'); - // Map Ogmios v6 response to Lucid's ProtocolParameters format - return { - minFeeA: result.minFeeCoefficient, - minFeeB: result.minFeeConstant?.ada?.lovelace ?? result.minFeeConstant, - maxTxSize: result.maxTransactionSize?.bytes ?? result.maxTransactionSize, - maxValSize: result.maxValueSize?.bytes ?? result.maxValueSize, - keyDeposit: BigInt(result.stakeCredentialDeposit?.ada?.lovelace ?? result.stakeCredentialDeposit ?? 2000000), - poolDeposit: BigInt(result.stakePoolDeposit?.ada?.lovelace ?? result.stakePoolDeposit ?? 500000000), - priceMem: result.scriptExecutionPrices?.memory - ? this.parseFraction(result.scriptExecutionPrices.memory) - : (result.prices?.memory ?? 0.0577), - priceStep: result.scriptExecutionPrices?.cpu - ? this.parseFraction(result.scriptExecutionPrices.cpu) - : (result.prices?.steps ?? 0.0000721), - maxTxExMem: BigInt(result.maxExecutionUnitsPerTransaction?.memory ?? 14000000), - maxTxExSteps: BigInt(result.maxExecutionUnitsPerTransaction?.cpu ?? 10000000000), - coinsPerUtxoByte: BigInt(result.minUtxoDepositCoefficient ?? result.coinsPerUtxoByte ?? 4310), - collateralPercentage: result.collateralPercentage ?? 150, - maxCollateralInputs: result.maxCollateralInputs ?? 3, - costModels: this.parseCostModels(result.plutusCostModels ?? result.costModels ?? {}), - minFeeRefScriptCostPerByte: result.minFeeReferenceScripts?.base ?? 15, - drepDeposit: BigInt(result.delegateRepresentativeDeposit?.ada?.lovelace ?? 500000000), - govActionDeposit: BigInt(result.governanceActionDeposit?.ada?.lovelace ?? 100000000000), - } as ProtocolParameters; + try { + // Map Ogmios v6 response to Lucid's ProtocolParameters format + // Defaults are sourced from the Vector public testnet (2026-03-31) + return { + minFeeA: result.minFeeCoefficient ?? 45, + minFeeB: result.minFeeConstant?.ada?.lovelace + ?? result.minFeeConstant?.lovelace + ?? (typeof result.minFeeConstant === 'number' ? result.minFeeConstant : 156253), + maxTxSize: result.maxTransactionSize?.bytes ?? result.maxTransactionSize ?? 16384, + maxValSize: result.maxValueSize?.bytes ?? result.maxValueSize ?? 5000, + keyDeposit: BigInt(result.stakeCredentialDeposit?.ada?.lovelace ?? result.stakeCredentialDeposit ?? 500000000), + poolDeposit: BigInt(result.stakePoolDeposit?.ada?.lovelace ?? result.stakePoolDeposit ?? 5000000000000), + priceMem: result.scriptExecutionPrices?.memory + ? this.parseFraction(result.scriptExecutionPrices.memory) + : (result.prices?.memory ?? 0.0577), + priceStep: result.scriptExecutionPrices?.cpu + ? this.parseFraction(result.scriptExecutionPrices.cpu) + : (result.prices?.steps ?? 0.0000721), + maxTxExMem: BigInt(result.maxExecutionUnitsPerTransaction?.memory ?? 16000000), + maxTxExSteps: BigInt(result.maxExecutionUnitsPerTransaction?.cpu ?? 10000000000), + coinsPerUtxoByte: BigInt(result.minUtxoDepositCoefficient ?? result.coinsPerUtxoByte ?? 4310), + collateralPercentage: result.collateralPercentage ?? 150, + maxCollateralInputs: result.maxCollateralInputs ?? 3, + costModels: this.parseCostModels(result.plutusCostModels ?? result.costModels ?? {}), + minFeeRefScriptCostPerByte: result.minFeeReferenceScripts?.base ?? 15, + drepDeposit: BigInt(result.delegateRepresentativeDeposit?.ada?.lovelace ?? 1000000000000), + govActionDeposit: BigInt(result.governanceActionDeposit?.ada?.lovelace ?? 1000000000), + } as ProtocolParameters; + } catch (err) { + console.error('[OgmiosProvider] Protocol parameter mapping failed:', err); + console.error('[OgmiosProvider] Raw Ogmios result:', JSON.stringify(result, null, 2)); + throw err; + } } private parseFraction(value: string | number): number { diff --git a/src/vector/vector.ts b/src/vector/vector.ts index 259ab73..4a79ba4 100644 --- a/src/vector/vector.ts +++ b/src/vector/vector.ts @@ -43,7 +43,12 @@ const VECTOR_EXPLORER_URL = process.env.VECTOR_EXPLORER_URL || 'https://vector.t // Helper function to format ADA amounts function lovelaceToAda(lovelace: string | number | bigint): string { - return (Number(BigInt(String(lovelace))) / 1_000_000).toFixed(6); + if (lovelace === undefined || lovelace === null) return '0.000000'; + try { + return (Number(BigInt(String(lovelace))) / 1_000_000).toFixed(6); + } catch { + return '0.000000'; + } } // Helper function to format asset name @@ -98,9 +103,13 @@ async function initLucid(mnemonic: string, accountIndex: number = 0) { // Get wallet info export async function getWalletInfo(mnemonic: string, accountIndex: number = 0): Promise { + console.error('[getWalletInfo] Initializing Lucid...'); const lucid = await initLucid(mnemonic, accountIndex); + console.error('[getWalletInfo] Getting address...'); const address = await lucid.wallet().address(); + console.error('[getWalletInfo] Querying UTxOs...'); const utxos = await lucid.utxosAt(address); + console.error(`[getWalletInfo] Found ${utxos.length} UTxOs`); let adaBalance = '0'; let tokenBalances: VectorToken[] = [];