Skip to content

Commit 14c32c0

Browse files
committed
refactor(wallet): update wallet building logic to support old and new multisig wallets
- Replaced the multisig wallet building function with a conditional approach that utilizes the MultisigSDK when stake keys are present. - Improved error handling for wallet building failures, providing clearer error messages. - Streamlined address generation by consolidating UTxO fetching into a single wallet address determination process.
1 parent 33e6023 commit 14c32c0

File tree

1 file changed

+46
-62
lines changed

1 file changed

+46
-62
lines changed

src/pages/api/v1/stats/run-snapshots-batch.ts

Lines changed: 46 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { cors, addCorsCacheBustingHeaders } from "@/lib/cors";
22
import type { NextApiRequest, NextApiResponse } from "next";
33
import { db } from "@/server/db";
4-
import { buildMultisigWallet } from "@/utils/common";
4+
import { buildWallet } from "@/utils/common";
5+
import { MultisigWallet, type MultisigKey } from "@/utils/multisigSDK";
56
import { getProvider } from "@/utils/get-provider";
6-
import { resolvePaymentKeyHash, serializeNativeScript } from "@meshsdk/core";
7-
import type { UTxO, NativeScript } from "@meshsdk/core";
7+
import { resolvePaymentKeyHash, resolveStakeKeyHash, type UTxO } from "@meshsdk/core";
88
import { getBalance } from "@/utils/getBalance";
99
import { addressToNetwork } from "@/utils/multisigSDK";
1010
import type { Wallet as DbWallet } from "@prisma/client";
@@ -266,69 +266,63 @@ export default async function handler(
266266
network = addressToNetwork(signerAddr);
267267
}
268268

269-
// Build multisig wallet for address determination
270-
const walletData = {
271-
id: wallet.id,
272-
name: wallet.name,
273-
signersAddresses: wallet.signersAddresses,
274-
numRequiredSigners: wallet.numRequiredSigners!,
275-
type: wallet.type || "atLeast",
276-
stakeCredentialHash: wallet.stakeCredentialHash,
277-
isArchived: wallet.isArchived,
278-
description: wallet.description,
279-
signersStakeKeys: wallet.signersStakeKeys,
280-
signersDRepKeys: wallet.signersDRepKeys,
281-
signersDescriptions: wallet.signersDescriptions,
282-
clarityApiKey: wallet.clarityApiKey,
283-
drepKey: null,
284-
scriptType: null,
285-
scriptCbor: wallet.scriptCbor,
286-
verified: wallet.verified,
287-
};
288-
289-
const mWallet = buildMultisigWallet(walletData, network);
290-
if (!mWallet) {
291-
console.error(`Failed to build multisig wallet for ${wallet.id.slice(0, 8)}...`);
269+
// Build wallet conditionally: use MultisigSDK ordering if signersStakeKeys exist
270+
let walletAddress: string;
271+
try {
272+
const hasStakeKeys = !!(wallet.signersStakeKeys && wallet.signersStakeKeys.length > 0);
273+
if (hasStakeKeys) {
274+
// Build MultisigSDK wallet with ordered keys
275+
const keys: MultisigKey[] = [];
276+
wallet.signersAddresses.forEach((addr: string, i: number) => {
277+
if (!addr) return;
278+
try {
279+
keys.push({ keyHash: resolvePaymentKeyHash(addr), role: 0, name: wallet.signersDescriptions[i] || "" });
280+
} catch {}
281+
});
282+
wallet.signersStakeKeys?.forEach((stakeKey: string, i: number) => {
283+
if (!stakeKey) return;
284+
try {
285+
keys.push({ keyHash: resolveStakeKeyHash(stakeKey), role: 2, name: wallet.signersDescriptions[i] || "" });
286+
} catch {}
287+
});
288+
if (keys.length === 0 && !wallet.stakeCredentialHash) {
289+
throw new Error("No valid keys or stakeCredentialHash provided");
290+
}
291+
const mWallet = new MultisigWallet(
292+
wallet.name,
293+
keys,
294+
wallet.description ?? "",
295+
wallet.numRequiredSigners ?? 1,
296+
network,
297+
wallet.stakeCredentialHash as undefined | string,
298+
(wallet.type as any) || "atLeast"
299+
);
300+
walletAddress = mWallet.getScript().address;
301+
} else {
302+
const builtWallet = buildWallet(wallet, network);
303+
walletAddress = builtWallet.address;
304+
}
305+
} catch (error) {
306+
const errorMessage = error instanceof Error ? error.message : 'Unknown wallet build error';
307+
console.error(`Failed to build wallet for ${wallet.id.slice(0, 8)}...:`, errorMessage);
308+
292309
failures.push({
293310
walletId: wallet.id.slice(0, 8),
294311
errorType: "wallet_build_failed",
295-
errorMessage: "Unable to build multisig wallet from provided data",
312+
errorMessage: "Unable to build wallet from provided data",
296313
walletStructure: getWalletStructure(wallet)
297314
});
298315
failedInBatch++;
299316
continue;
300317
}
301318

302-
// Generate addresses from the built wallet
303-
const nativeScript = {
304-
type: wallet.type || "atLeast",
305-
scripts: wallet.signersAddresses.map((addr: string) => ({
306-
type: "sig",
307-
keyHash: resolvePaymentKeyHash(addr),
308-
})),
309-
};
310-
if (nativeScript.type == "atLeast") {
311-
//@ts-ignore
312-
nativeScript.required = wallet.numRequiredSigners!;
313-
}
314-
315-
const paymentAddress = serializeNativeScript(
316-
nativeScript as NativeScript,
317-
wallet.stakeCredentialHash as undefined | string,
318-
network,
319-
).address;
320-
321-
const stakeableAddress = mWallet.getScript().address;
322-
323319
// Determine which address to use
324320
const blockchainProvider = getProvider(network);
325321

326-
let paymentUtxos: UTxO[] = [];
327-
let stakeableUtxos: UTxO[] = [];
322+
let utxos: UTxO[] = [];
328323

329324
try {
330-
paymentUtxos = await blockchainProvider.fetchAddressUTxOs(paymentAddress);
331-
stakeableUtxos = await blockchainProvider.fetchAddressUTxOs(stakeableAddress);
325+
utxos = await blockchainProvider.fetchAddressUTxOs(walletAddress);
332326
} catch (utxoError) {
333327
const errorMessage = utxoError instanceof Error ? utxoError.message : 'Unknown UTxO fetch error';
334328
console.error(`Failed to fetch UTxOs for wallet ${wallet.id.slice(0, 8)}...:`, errorMessage);
@@ -343,16 +337,6 @@ export default async function handler(
343337
failedInBatch++;
344338
continue;
345339
}
346-
347-
const paymentAddrEmpty = paymentUtxos.length === 0;
348-
let walletAddress = paymentAddress;
349-
350-
if (paymentAddrEmpty && mWallet.stakingEnabled()) {
351-
walletAddress = stakeableAddress;
352-
}
353-
354-
// Use the UTxOs from the selected address
355-
let utxos: UTxO[] = walletAddress === stakeableAddress ? stakeableUtxos : paymentUtxos;
356340

357341
// If we still have no UTxOs, try the other network as fallback
358342
if (utxos.length === 0) {

0 commit comments

Comments
 (0)