Skip to content

Commit da114ab

Browse files
authored
add collateral utxo even if it gets ignored, and set up change address properly (#4442)
2 parents ea5fdd7 + aad19da commit da114ab

File tree

2 files changed

+62
-10
lines changed

2 files changed

+62
-10
lines changed

mobile/src/features/Airdrop/api/redemptionApi.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,13 @@ export const redemptionApi = {
184184
request: {
185185
changeAddress: request.change_address,
186186
fundingUtxosCount: request.funding_utxos.length,
187-
collateralUtxosCount: request.collateral_utxos.length,
188187
fundingUtxosPreview: request.funding_utxos
189188
.slice(0, 2)
190189
.map((utxo) => `${utxo.substring(0, 32)}...`),
190+
collateralUtxosCount: request.collateral_utxos.length,
191+
collateralUtxosPreview: request.collateral_utxos
192+
.slice(0, 2)
193+
.map((utxo) => `${utxo.substring(0, 32)}...`),
191194
},
192195
})
193196

mobile/src/features/Airdrop/common/useRedeemThaw.ts

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import {RawUtxo} from '@yoroi/api'
2-
import {CardanoMobileWrapped} from '@yoroi/cardano-wallet'
2+
import {
3+
CardanoMobileWrapped,
4+
collateralConfig,
5+
utxosMaker,
6+
} from '@yoroi/cardano-wallet'
37
import type {SelectionStrategy} from '@yoroi/tx'
48
import {rawUtxoToModernUtxo, selectUtxos} from '@yoroi/tx'
59
import {Balance} from '@yoroi/types'
@@ -57,8 +61,8 @@ export const useRedeemThaw = () => {
5761
[primaryTokenId]: '5000000' as Balance.Quantity, // 5 ADA in lovelace
5862
}
5963

60-
const fundingUtxosHex = await CardanoMobileWrapped.cslScope(
61-
async (csl) => {
64+
const {fundingUtxosHex, collateralUtxosHex} =
65+
await CardanoMobileWrapped.cslScope(async (csl) => {
6266
// Convert RawUtxo[] to ModernUtxo[] using current pattern
6367
const rawUtxos = wallet.utxos()
6468

@@ -91,6 +95,20 @@ export const useRedeemThaw = () => {
9195
throw new Error('No UTXOs available with sufficient funds')
9296
}
9397

98+
// Track which UTXOs were selected for funding (by utxo_id from RawUtxo)
99+
// Match ModernUtxo to RawUtxo by txHash and txIndex
100+
const selectedFundingUtxoIds = new Set<string>()
101+
selection.selected.forEach((modernUtxo) => {
102+
const matchingRawUtxo = rawUtxos.find(
103+
(rawUtxo) =>
104+
rawUtxo.tx_hash === modernUtxo.txHash &&
105+
rawUtxo.tx_index === modernUtxo.txIndex,
106+
)
107+
if (matchingRawUtxo) {
108+
selectedFundingUtxoIds.add(matchingRawUtxo.utxo_id)
109+
}
110+
})
111+
94112
// Convert ModernUtxo to hex strings using toTransactionUnspentOutput
95113
const utxoHexStrings = await Promise.all(
96114
selection.selected.map(async (utxo) => {
@@ -99,18 +117,49 @@ export const useRedeemThaw = () => {
99117
}),
100118
)
101119

102-
return utxoHexStrings
103-
},
104-
)
120+
// Find collateral candidates (pure ADA, <= 5 ADA)
121+
const utxosList = utxosMaker(rawUtxos, collateralConfig)
122+
const collateralCandidates = utxosList.findCollateralCandidates()
123+
124+
// Filter out UTXOs already selected for funding
125+
const availableCollateral = collateralCandidates.filter(
126+
(utxo: RawUtxo) => !selectedFundingUtxoIds.has(utxo.utxo_id),
127+
)
128+
129+
// Convert the first available collateral UTXO to hex format
130+
let collateralUtxosHex: string[] = []
131+
if (availableCollateral.length > 0) {
132+
const collateralUtxo = availableCollateral[0]!
133+
// Find the corresponding ModernUtxo to convert it
134+
const collateralModernUtxo = modernUtxos.find(
135+
(utxo) =>
136+
utxo.txHash === collateralUtxo.tx_hash &&
137+
utxo.txIndex === collateralUtxo.tx_index,
138+
)
139+
140+
if (collateralModernUtxo) {
141+
const cslUtxo =
142+
collateralModernUtxo.toTransactionUnspentOutput(csl)
143+
collateralUtxosHex = [
144+
Buffer.from(cslUtxo.toBytes()).toString('hex'),
145+
]
146+
}
147+
}
148+
149+
return {
150+
fundingUtxosHex: utxoHexStrings,
151+
collateralUtxosHex,
152+
}
153+
})
105154

106-
// Get change address
107-
const changeAddress = wallet.getChangeAddress('multiple')
155+
// Get change address (respects wallet's address mode - single uses first address, multiple uses unused address)
156+
const changeAddress = wallet.getChangeAddress(meta.addressMode)
108157

109158
// Build transaction request
110159
const buildRequest: BuildTransactionRequest = {
111160
change_address: changeAddress,
112161
funding_utxos: fundingUtxosHex,
113-
collateral_utxos: [],
162+
collateral_utxos: collateralUtxosHex,
114163
}
115164

116165
logger.info(

0 commit comments

Comments
 (0)