Fix BigInt crash in protocol parameter parsing, add docker-compose
Protocol parameter fields (minFeeA, minFeeB, maxTxSize, maxValSize) lacked fallback defaults, causing "Cannot convert undefined to a BigInt" when Lucid-Evolution processed them. Added safe defaults sourced from Vector public testnet and updated deposit values to match. Made lovelaceToAda() defensive against undefined/null. Added diagnostic logging to getWalletInfo and getProtocolParameters error paths. Converted Dockerfile to multi-stage build and added docker-compose.yml with inline Vector testnet environment config. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
10
Dockerfile
10
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
|
FROM node:22-alpine
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm ci --omit=dev
|
RUN npm ci --omit=dev
|
||||||
COPY build/ ./build/
|
COPY --from=builder /app/build/ ./build/
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
CMD ["node", "build/index.js"]
|
CMD ["node", "build/index.js"]
|
||||||
|
|||||||
12
docker-compose.yml
Normal file
12
docker-compose.yml
Normal file
@@ -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
|
||||||
@@ -64,30 +64,39 @@ export class OgmiosProvider implements Provider {
|
|||||||
async getProtocolParameters(): Promise<ProtocolParameters> {
|
async getProtocolParameters(): Promise<ProtocolParameters> {
|
||||||
const result = await this.rpc('queryLedgerState/protocolParameters');
|
const result = await this.rpc('queryLedgerState/protocolParameters');
|
||||||
|
|
||||||
// Map Ogmios v6 response to Lucid's ProtocolParameters format
|
try {
|
||||||
return {
|
// Map Ogmios v6 response to Lucid's ProtocolParameters format
|
||||||
minFeeA: result.minFeeCoefficient,
|
// Defaults are sourced from the Vector public testnet (2026-03-31)
|
||||||
minFeeB: result.minFeeConstant?.ada?.lovelace ?? result.minFeeConstant,
|
return {
|
||||||
maxTxSize: result.maxTransactionSize?.bytes ?? result.maxTransactionSize,
|
minFeeA: result.minFeeCoefficient ?? 45,
|
||||||
maxValSize: result.maxValueSize?.bytes ?? result.maxValueSize,
|
minFeeB: result.minFeeConstant?.ada?.lovelace
|
||||||
keyDeposit: BigInt(result.stakeCredentialDeposit?.ada?.lovelace ?? result.stakeCredentialDeposit ?? 2000000),
|
?? result.minFeeConstant?.lovelace
|
||||||
poolDeposit: BigInt(result.stakePoolDeposit?.ada?.lovelace ?? result.stakePoolDeposit ?? 500000000),
|
?? (typeof result.minFeeConstant === 'number' ? result.minFeeConstant : 156253),
|
||||||
priceMem: result.scriptExecutionPrices?.memory
|
maxTxSize: result.maxTransactionSize?.bytes ?? result.maxTransactionSize ?? 16384,
|
||||||
? this.parseFraction(result.scriptExecutionPrices.memory)
|
maxValSize: result.maxValueSize?.bytes ?? result.maxValueSize ?? 5000,
|
||||||
: (result.prices?.memory ?? 0.0577),
|
keyDeposit: BigInt(result.stakeCredentialDeposit?.ada?.lovelace ?? result.stakeCredentialDeposit ?? 500000000),
|
||||||
priceStep: result.scriptExecutionPrices?.cpu
|
poolDeposit: BigInt(result.stakePoolDeposit?.ada?.lovelace ?? result.stakePoolDeposit ?? 5000000000000),
|
||||||
? this.parseFraction(result.scriptExecutionPrices.cpu)
|
priceMem: result.scriptExecutionPrices?.memory
|
||||||
: (result.prices?.steps ?? 0.0000721),
|
? this.parseFraction(result.scriptExecutionPrices.memory)
|
||||||
maxTxExMem: BigInt(result.maxExecutionUnitsPerTransaction?.memory ?? 14000000),
|
: (result.prices?.memory ?? 0.0577),
|
||||||
maxTxExSteps: BigInt(result.maxExecutionUnitsPerTransaction?.cpu ?? 10000000000),
|
priceStep: result.scriptExecutionPrices?.cpu
|
||||||
coinsPerUtxoByte: BigInt(result.minUtxoDepositCoefficient ?? result.coinsPerUtxoByte ?? 4310),
|
? this.parseFraction(result.scriptExecutionPrices.cpu)
|
||||||
collateralPercentage: result.collateralPercentage ?? 150,
|
: (result.prices?.steps ?? 0.0000721),
|
||||||
maxCollateralInputs: result.maxCollateralInputs ?? 3,
|
maxTxExMem: BigInt(result.maxExecutionUnitsPerTransaction?.memory ?? 16000000),
|
||||||
costModels: this.parseCostModels(result.plutusCostModels ?? result.costModels ?? {}),
|
maxTxExSteps: BigInt(result.maxExecutionUnitsPerTransaction?.cpu ?? 10000000000),
|
||||||
minFeeRefScriptCostPerByte: result.minFeeReferenceScripts?.base ?? 15,
|
coinsPerUtxoByte: BigInt(result.minUtxoDepositCoefficient ?? result.coinsPerUtxoByte ?? 4310),
|
||||||
drepDeposit: BigInt(result.delegateRepresentativeDeposit?.ada?.lovelace ?? 500000000),
|
collateralPercentage: result.collateralPercentage ?? 150,
|
||||||
govActionDeposit: BigInt(result.governanceActionDeposit?.ada?.lovelace ?? 100000000000),
|
maxCollateralInputs: result.maxCollateralInputs ?? 3,
|
||||||
} as ProtocolParameters;
|
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 {
|
private parseFraction(value: string | number): number {
|
||||||
|
|||||||
@@ -43,7 +43,12 @@ const VECTOR_EXPLORER_URL = process.env.VECTOR_EXPLORER_URL || 'https://vector.t
|
|||||||
|
|
||||||
// Helper function to format ADA amounts
|
// Helper function to format ADA amounts
|
||||||
function lovelaceToAda(lovelace: string | number | bigint): string {
|
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
|
// Helper function to format asset name
|
||||||
@@ -98,9 +103,13 @@ async function initLucid(mnemonic: string, accountIndex: number = 0) {
|
|||||||
|
|
||||||
// Get wallet info
|
// Get wallet info
|
||||||
export async function getWalletInfo(mnemonic: string, accountIndex: number = 0): Promise<VectorWalletInfo> {
|
export async function getWalletInfo(mnemonic: string, accountIndex: number = 0): Promise<VectorWalletInfo> {
|
||||||
|
console.error('[getWalletInfo] Initializing Lucid...');
|
||||||
const lucid = await initLucid(mnemonic, accountIndex);
|
const lucid = await initLucid(mnemonic, accountIndex);
|
||||||
|
console.error('[getWalletInfo] Getting address...');
|
||||||
const address = await lucid.wallet().address();
|
const address = await lucid.wallet().address();
|
||||||
|
console.error('[getWalletInfo] Querying UTxOs...');
|
||||||
const utxos = await lucid.utxosAt(address);
|
const utxos = await lucid.utxosAt(address);
|
||||||
|
console.error(`[getWalletInfo] Found ${utxos.length} UTxOs`);
|
||||||
|
|
||||||
let adaBalance = '0';
|
let adaBalance = '0';
|
||||||
let tokenBalances: VectorToken[] = [];
|
let tokenBalances: VectorToken[] = [];
|
||||||
|
|||||||
Reference in New Issue
Block a user