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
|
||||
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"]
|
||||
|
||||
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> {
|
||||
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 {
|
||||
|
||||
@@ -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<VectorWalletInfo> {
|
||||
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[] = [];
|
||||
|
||||
Reference in New Issue
Block a user