|
35 | 35 | VERIFICATION_KEY_HASH_SIZE,
|
36 | 36 | PoolKeyHash,
|
37 | 37 | TransactionId,
|
| 38 | + ScriptHash, |
38 | 39 | VerificationKeyHash,
|
39 | 40 | )
|
40 | 41 | from pycardano.key import VerificationKey
|
@@ -2326,3 +2327,88 @@ def test_collateral_no_duplicates(chain_context):
|
2326 | 2327 | total_collateral_input
|
2327 | 2328 | == Value(tx_body.total_collateral) + tx_body.collateral_return.amount
|
2328 | 2329 | ), "The total collateral input amount should match the sum of the selected UTxOs"
|
| 2330 | + |
| 2331 | + |
| 2332 | +def test_token_transfer_with_change(chain_context): |
| 2333 | + """Test token transfer with change address handling. |
| 2334 | +
|
| 2335 | + Replicates issue where transaction fails with 'Input UTxOs depleted' when: |
| 2336 | + - Input 1: 4 ADA |
| 2337 | + - Input 2: ~1.03 ADA + 1,876,083 tokens |
| 2338 | + - Output: ~1.32 ADA + 382 tokens |
| 2339 | + - Expected change should handle remaining ADA and tokens |
| 2340 | + """ |
| 2341 | + # Create the vault address that holds tokens |
| 2342 | + vault_address = Address.from_primitive( |
| 2343 | + "addr_test1vrs324jltsc0ssuptpa5ngpfk89cps92xa99a2t6vlg6kdqtm5qnv" |
| 2344 | + ) |
| 2345 | + |
| 2346 | + # Create receiver address |
| 2347 | + receiver_address = Address.from_primitive( |
| 2348 | + "addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x" |
| 2349 | + ) |
| 2350 | + |
| 2351 | + # Create token details |
| 2352 | + token_policy_id = ScriptHash(bytes.fromhex("1f847bb9ac60e869780037c0510dbd89f745316db7ec4fee81ff1e97")) |
| 2353 | + token_name = AssetName(b"dux_1") |
| 2354 | + |
| 2355 | + # Create the two input UTXOs and patch chain_context.utxos |
| 2356 | + with patch.object(chain_context, "utxos") as mock_utxos: |
| 2357 | + mock_utxos.return_value = [ |
| 2358 | + UTxO( |
| 2359 | + TransactionInput.from_primitive([ |
| 2360 | + "e11efc26f94a3cbf724dc052c43abf36f7a631a831acc6d783f1c9c8c52725c5", |
| 2361 | + 0 |
| 2362 | + ]), |
| 2363 | + TransactionOutput( |
| 2364 | + vault_address, |
| 2365 | + Value( |
| 2366 | + 1038710, # ~1.03 ADA |
| 2367 | + MultiAsset.from_primitive({ |
| 2368 | + token_policy_id.payload: { |
| 2369 | + b"dux_1": 1876083 # 1,876,083 tokens |
| 2370 | + } |
| 2371 | + }) |
| 2372 | + ) |
| 2373 | + ) |
| 2374 | + ) |
| 2375 | + ] |
| 2376 | + |
| 2377 | + # Create transaction builder |
| 2378 | + tx_builder = TransactionBuilder(chain_context) |
| 2379 | + |
| 2380 | + # Add inputs - using add_input_address for the vault input |
| 2381 | + tx_builder.add_input_address(vault_address) |
| 2382 | + tx_builder.add_input(UTxO( |
| 2383 | + TransactionInput.from_primitive([b"1" * 32, 0]), |
| 2384 | + TransactionOutput(receiver_address, Value(4000000)) # 4 ADA input |
| 2385 | + )) |
| 2386 | + |
| 2387 | + # Add output for receiver |
| 2388 | + output_value = Value( |
| 2389 | + 1326255, # ~1.32 ADA |
| 2390 | + MultiAsset.from_primitive({ |
| 2391 | + token_policy_id.payload: { |
| 2392 | + b"dux_1": 382 # 382 tokens |
| 2393 | + } |
| 2394 | + }) |
| 2395 | + ) |
| 2396 | + tx_builder.add_output(TransactionOutput(receiver_address, output_value)) |
| 2397 | + |
| 2398 | + # Build transaction with change going back to vault |
| 2399 | + tx = tx_builder.build(change_address=vault_address, merge_change=True) |
| 2400 | + |
| 2401 | + # Verify the transaction outputs |
| 2402 | + assert len(tx.outputs) == 2 # One for receiver, one for change |
| 2403 | + |
| 2404 | + # Verify receiver output |
| 2405 | + receiver_output = tx.outputs[0] |
| 2406 | + assert receiver_output.address == receiver_address |
| 2407 | + assert receiver_output.amount.coin == 1326255 |
| 2408 | + assert receiver_output.amount.multi_asset[token_policy_id][token_name] == 382 |
| 2409 | + |
| 2410 | + # Verify change output |
| 2411 | + change_output = tx.outputs[1] |
| 2412 | + assert change_output.address == vault_address |
| 2413 | + assert change_output.amount.coin == 4000000 + 1038710 - 1326255 - tx.fee |
| 2414 | + assert change_output.amount.multi_asset[token_policy_id][token_name] == 1876083 - 382 |
0 commit comments