11import { cors , addCorsCacheBustingHeaders } from "@/lib/cors" ;
22import type { NextApiRequest , NextApiResponse } from "next" ;
33import { db } from "@/server/db" ;
4- import { buildMultisigWallet } from "@/utils/common" ;
4+ import { buildWallet } from "@/utils/common" ;
5+ import { MultisigWallet , type MultisigKey } from "@/utils/multisigSDK" ;
56import { 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" ;
88import { getBalance } from "@/utils/getBalance" ;
99import { addressToNetwork } from "@/utils/multisigSDK" ;
1010import type { Wallet as DbWallet } from "@prisma/client" ;
@@ -259,76 +259,76 @@ export default async function handler(
259259 try {
260260 console . log ( ` Processing wallet: (${ wallet . id . slice ( 0 , 8 ) } ...)` ) ;
261261
262- // Determine network from signer addresses
262+ // Determine network from signer addresses, fallback to signer stake keys
263263 let network = 1 ; // Default to mainnet
264264 if ( wallet . signersAddresses . length > 0 ) {
265265 const signerAddr = wallet . signersAddresses [ 0 ] ! ;
266266 network = addressToNetwork ( signerAddr ) ;
267+ } else if ( wallet . signersStakeKeys && wallet . signersStakeKeys . length > 0 ) {
268+ const stakeAddr = wallet . signersStakeKeys . find ( ( s ) => ! ! s ) ;
269+ if ( stakeAddr ) {
270+ network = addressToNetwork ( stakeAddr ) ;
271+ }
267272 }
268273
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 ) } ...` ) ;
274+ // Build wallet conditionally: use MultisigSDK ordering if signersStakeKeys exist
275+ let walletAddress : string ;
276+ try {
277+ const hasStakeKeys = ! ! ( wallet . signersStakeKeys && wallet . signersStakeKeys . length > 0 ) ;
278+ if ( hasStakeKeys ) {
279+ // Build MultisigSDK wallet with ordered keys
280+ const keys : MultisigKey [ ] = [ ] ;
281+ wallet . signersAddresses . forEach ( ( addr : string , i : number ) => {
282+ if ( ! addr ) return ;
283+ try {
284+ keys . push ( { keyHash : resolvePaymentKeyHash ( addr ) , role : 0 , name : wallet . signersDescriptions [ i ] || "" } ) ;
285+ } catch { }
286+ } ) ;
287+ wallet . signersStakeKeys ?. forEach ( ( stakeKey : string , i : number ) => {
288+ if ( ! stakeKey ) return ;
289+ try {
290+ keys . push ( { keyHash : resolveStakeKeyHash ( stakeKey ) , role : 2 , name : wallet . signersDescriptions [ i ] || "" } ) ;
291+ } catch { }
292+ } ) ;
293+ if ( keys . length === 0 && ! wallet . stakeCredentialHash ) {
294+ throw new Error ( "No valid keys or stakeCredentialHash provided" ) ;
295+ }
296+ const mWallet = new MultisigWallet (
297+ wallet . name ,
298+ keys ,
299+ wallet . description ?? "" ,
300+ wallet . numRequiredSigners ?? 1 ,
301+ network ,
302+ wallet . stakeCredentialHash as undefined | string ,
303+ ( wallet . type as any ) || "atLeast"
304+ ) ;
305+ walletAddress = mWallet . getScript ( ) . address ;
306+ } else {
307+ // Fallback: build the wallet without enforcing key ordering (legacy payment-script build)
308+ const builtWallet = buildWallet ( wallet , network ) ;
309+ walletAddress = builtWallet . address ;
310+ }
311+ } catch ( error ) {
312+ const errorMessage = error instanceof Error ? error . message : 'Unknown wallet build error' ;
313+ console . error ( `Failed to build wallet for ${ wallet . id . slice ( 0 , 8 ) } ...:` , errorMessage ) ;
314+
292315 failures . push ( {
293316 walletId : wallet . id . slice ( 0 , 8 ) ,
294317 errorType : "wallet_build_failed" ,
295- errorMessage : "Unable to build multisig wallet from provided data" ,
318+ errorMessage : "Unable to build wallet from provided data" ,
296319 walletStructure : getWalletStructure ( wallet )
297320 } ) ;
298321 failedInBatch ++ ;
299322 continue ;
300323 }
301324
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-
323325 // Determine which address to use
324326 const blockchainProvider = getProvider ( network ) ;
325327
326- let paymentUtxos : UTxO [ ] = [ ] ;
327- let stakeableUtxos : UTxO [ ] = [ ] ;
328+ let utxos : UTxO [ ] = [ ] ;
328329
329330 try {
330- paymentUtxos = await blockchainProvider . fetchAddressUTxOs ( paymentAddress ) ;
331- stakeableUtxos = await blockchainProvider . fetchAddressUTxOs ( stakeableAddress ) ;
331+ utxos = await blockchainProvider . fetchAddressUTxOs ( walletAddress ) ;
332332 } catch ( utxoError ) {
333333 const errorMessage = utxoError instanceof Error ? utxoError . message : 'Unknown UTxO fetch error' ;
334334 console . error ( `Failed to fetch UTxOs for wallet ${ wallet . id . slice ( 0 , 8 ) } ...:` , errorMessage ) ;
@@ -343,16 +343,6 @@ export default async function handler(
343343 failedInBatch ++ ;
344344 continue ;
345345 }
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 ;
356346
357347 // If we still have no UTxOs, try the other network as fallback
358348 if ( utxos . length === 0 ) {
0 commit comments