Skip to content

Commit ae4abe8

Browse files
authored
fix swap cancel (#4436)
2 parents a98cdfb + 31d3ba4 commit ae4abe8

File tree

3 files changed

+53
-18
lines changed

3 files changed

+53
-18
lines changed

mobile/packages/cardano-wallet/common/signatureUtils.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,23 @@ const getRequiredSigners = async (
104104
})
105105

106106
const getAddressAddressing = (bech32Address: string) => {
107+
// Check if wallet actually controls this address (payment key)
108+
const addressBranded = Branded.asAddress(bech32Address)
109+
const internalIndex = wallet.internalAddresses().indexOf(addressBranded)
110+
const externalIndex = wallet.externalAddresses().indexOf(addressBranded)
111+
const walletControlsAddress = internalIndex !== -1 || externalIndex !== -1
112+
113+
// If wallet doesn't control the address and we're in strict mode, return null
114+
if (!walletControlsAddress && !partial) {
115+
return null
116+
}
117+
118+
// If wallet doesn't control the address, don't return addressing even in partial mode
119+
// This prevents signing for addresses we don't control (e.g., Minswap payment key + our staking key)
120+
if (!walletControlsAddress) {
121+
return null
122+
}
123+
107124
const path = getDerivationPathForAddress(
108125
bech32Address,
109126
wallet,

mobile/packages/tx/ledger/plutus.ts

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,24 +71,31 @@ export const createLedgerPlutusPayload = async (
7171

7272
const originalRequiredSigners = getRequiredSigners(body)
7373

74-
const requiredSigners = originalRequiredSigners.map((s) => {
75-
const paymentStakeCredential = csl.Credential.fromKeyhash(s)
76-
const stakeCredential = csl.Credential.fromKeyhash(stakeVKHash)
77-
const baseAddress = csl.BaseAddress.new(
78-
networkId,
79-
paymentStakeCredential,
80-
stakeCredential,
81-
)
82-
const addressing = getAddressAddressing(
83-
baseAddress.toAddress().toBech32(undefined),
84-
)
85-
if (!addressing)
86-
throw new Error(
87-
`Could not find addressing for required signer: ${s.toHex()}`,
74+
// Only include required signers that the wallet actually controls
75+
// Skip signers we don't control (e.g., Minswap's payment key + our staking key)
76+
const requiredSigners = originalRequiredSigners
77+
.map((s) => {
78+
const paymentStakeCredential = csl.Credential.fromKeyhash(s)
79+
const stakeCredential = csl.Credential.fromKeyhash(stakeVKHash)
80+
const baseAddress = csl.BaseAddress.new(
81+
networkId,
82+
paymentStakeCredential,
83+
stakeCredential,
8884
)
89-
const path = addressing.path
90-
return {type: TxRequiredSignerType.PATH as const, path}
91-
})
85+
const addressing = getAddressAddressing(
86+
baseAddress.toAddress().toBech32(undefined),
87+
)
88+
if (!addressing) {
89+
// Skip if wallet doesn't control this address
90+
return null
91+
}
92+
const path = addressing.path
93+
return {type: TxRequiredSignerType.PATH as const, path}
94+
})
95+
.filter(
96+
(s): s is {type: TxRequiredSignerType.PATH; path: number[]} =>
97+
s !== null,
98+
)
9299

93100
const inputs = body.inputs()
94101
const inputsArray: TxInput[] = []

mobile/packages/tx/ledger/signers.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,21 @@ const getRequiredSignersAddressing = async ({
158158
const addressingArray: Addressing[] = []
159159

160160
for (const signer of signersArray) {
161-
if (stakingKeyPath) {
161+
// Check if this required signer matches the wallet's staking key hash
162+
const signerKeyHashHex = signer.toHex()
163+
const walletStakingKeyHashHex = stakeVKHash.toHex()
164+
const isStakingKeySigner = signerKeyHashHex === walletStakingKeyHashHex
165+
166+
if (stakingKeyPath && isStakingKeySigner) {
167+
// Only add staking key signer if the required signer actually matches our staking key
162168
addressingArray.push({
163169
path: stakingKeyPath,
164170
startLevel: 1,
165171
})
166172
continue
167173
}
168174

175+
// For payment key signers, construct the address and check if wallet controls it
169176
const paymentStakeCredential = wasm.Credential.fromKeyhash(signer)
170177
const stakeCredential = wasm.Credential.fromKeyhash(stakeVKHash)
171178
const baseAddress = wasm.BaseAddress.new(
@@ -175,14 +182,18 @@ const getRequiredSignersAddressing = async ({
175182
)
176183
const bech32Address = baseAddress.toAddress().toBech32(undefined)
177184
const addressing = getAddressAddressing(bech32Address)
185+
186+
// Only include if we can get addressing AND the address is actually controlled by the wallet
178187
if (!addressing) {
179188
if (!partial) {
180189
throw new Error(
181190
`Could not find addressing for required signer: ${signer.toHex()}`,
182191
)
183192
}
193+
// Skip if we don't control this address (partial mode)
184194
continue
185195
}
196+
186197
addressingArray.push(addressing)
187198
}
188199

0 commit comments

Comments
 (0)