feat(swift-sdk): expose rich transaction fields in WalletTransaction#3481
feat(swift-sdk): expose rich transaction fields in WalletTransaction#3481llbartekll wants to merge 2 commits intov3.1-devfrom
Conversation
The FFI's FFITransactionRecord already delivers input details, output
details, transaction type, direction, and InstantSend lock status —
but WalletTransaction was dropping them on the floor. This commit maps
the remaining fields so downstream consumers (dashwallet-ios) can
display full transaction details.
- Add TxIO struct (address, amount, isMine) for input/output records
- Extend WalletTransaction with inputs, outputs, txType, direction,
instantSendLocked (all with defaults for backward compatibility)
- Update getTransactions() mapping to read from ffiTx.input_details,
ffiTx.output_details, ffiTx.transaction_type, ffiTx.direction,
ffiTx.context.islock_data
Note: FFIOutputDetail only has { index, role } — no address or amount.
Output addresses are not available from the FFI yet. Input addresses
are fully populated from FFIInputDetail.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
FFIOutputDetail now includes address and value fields (added in rust-dashcore PR #640). Update the getTransactions() mapping to read them into TxIO, enabling dashwallet-ios to display "Received at" and "Sent to" addresses in the transaction detail screen. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
📝 WalkthroughWalkthroughThis pull request extends the Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Review GateCommit:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift`:
- Around line 100-107: The input mapping currently hardcodes isMine: false in
ManagedAccount.swift when building inputs, causing misclassification; update the
loop that builds inputs (the section that iterates ffiTx.input_details and
appends TxIO) to inspect the FFIInputDetail.role field (analogous to the output
handling that checks detail.role == FFI_OUTPUT_ROLE_RECEIVED || detail.role ==
FFI_OUTPUT_ROLE_CHANGE) and set isMine = true when the role indicates the input
is wallet-owned, otherwise false; if FFIInputDetail does not expose a role
field, document that fact in a comment and request exposing ownership metadata
from the FFI so inputs can be classified properly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bf28c4df-585c-42fe-8228-64c201125e2f
📒 Files selected for processing (1)
packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift
| // Convert input details | ||
| var inputs: [TxIO] = [] | ||
| if ffiTx.input_details_count > 0, let inputsPtr = ffiTx.input_details { | ||
| for j in 0..<ffiTx.input_details_count { | ||
| let detail = inputsPtr.advanced(by: j).pointee | ||
| let address = detail.address != nil ? String(cString: detail.address) : "" | ||
| inputs.append(TxIO(address: address, amount: detail.value, isMine: false)) | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Locate FFI type declarations surfaced in repo sources/interfaces.
fd -i 'DashSDKFFI|ffi' .
# 2) Inspect symbols related to input details and ownership flags.
rg -n -C3 --iglob '*.h' --iglob '*.swiftinterface' --iglob '*.swift' \
'FFIInputDetail|input_details|is_mine|isMine|role|address|value'Repository: dashpay/platform
Length of output: 50374
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the ManagedAccount.swift file to see the context around lines 100-107
echo "=== ManagedAccount.swift lines 95-115 ==="
sed -n '95,115p' packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift
echo -e "\n=== Searching for FFIInputDetail definition ==="
# Search in FFI-related files for FFIInputDetail struct/type definition
rg -n 'struct FFIInputDetail|class FFIInputDetail|FFIInputDetail.*{' packages/swift-sdk/ --type swift --type c --type h -A 10 | head -100
echo -e "\n=== Searching for input_details and is_mine patterns ==="
# Look for is_mine or similar ownership fields in FFI bindings
rg -n 'is_mine|isMine' packages/swift-sdk/Sources/SwiftDashSDK/FFI/ --type swift --type h -B 2 -A 2
echo -e "\n=== Checking FFI header files for input detail structure ==="
# Search in header files for input detail field definitions
fd -e h packages/swift-sdk/Sources/SwiftDashSDK/FFI/ -exec grep -l "input_details" {} \;Repository: dashpay/platform
Length of output: 1327
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Simpler search for FFIInputDetail
echo "=== Searching for FFIInputDetail definition ==="
rg 'FFIInputDetail' packages/swift-sdk/Sources/SwiftDashSDK/FFI/ --type swift --type h -B 2 -A 5
echo -e "\n=== Looking for input detail structure in header files ==="
find packages/swift-sdk -name "*.h" -type f | xargs grep -l "input_detail" 2>/dev/null || echo "No .h files with input_detail found"
echo -e "\n=== Searching for is_mine field in codebase ==="
rg 'is_mine|isMine' packages/swift-sdk/Sources/SwiftDashSDK/ --type swift -B 1 -A 1
echo -e "\n=== Looking at the full TxIO struct definition ==="
rg 'struct TxIO' packages/swift-sdk/Sources/SwiftDashSDK/ --type swift -A 10
echo -e "\n=== Check imports and FFI files ==="
ls -la packages/swift-sdk/Sources/SwiftDashSDK/FFI/Repository: dashpay/platform
Length of output: 107
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Searching entire repo for FFIInputDetail ==="
rg 'FFIInputDetail' . --type swift --type h --type rust 2>/dev/null | head -30
echo -e "\n=== Looking for input_detail in FFI packages ==="
rg 'input_detail' packages/rs-sdk-ffi/ packages/rs-platform-wallet-ffi/ --type rust --type h 2>/dev/null | head -30
echo -e "\n=== Check ManagedAccount.swift for TxIO and isMine usage ==="
rg 'struct TxIO|class TxIO|var isMine' packages/swift-sdk/Sources/SwiftDashSDK/ --type swift -A 5 -B 1
echo -e "\n=== Check if similar patterns with ownership exist elsewhere ==="
rg 'isMine.*false|isMine.*true' packages/swift-sdk/ --type swift
echo -e "\n=== Look for transaction parsing to understand data available ==="
grep -r 'input_details_count\|output_details_count' packages/swift-sdk/ --include="*.swift" 2>/dev/null | head -20Repository: dashpay/platform
Length of output: 108
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Read ManagedAccount.swift imports and beginning ==="
head -50 packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift
echo -e "\n=== Check for bridging header ==="
find packages/swift-sdk -name "*Bridging*" -o -name "*bridging*" 2>/dev/null | xargs cat 2>/dev/null
echo -e "\n=== Look at FFI module structure ==="
ls -la packages/swift-sdk/Sources/SwiftDashSDK/FFI/ 2>/dev/null || echo "FFI dir listing failed"
echo -e "\n=== Check if ffiTx is defined in module imports ==="
rg 'import.*FFI|typealias.*ffiTx' packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ --type swift -B 2 -A 2
echo -e "\n=== Look for WalletTransaction struct to understand input handling ==="
rg 'struct WalletTransaction|func getTransactions' packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift -A 20 | head -60Repository: dashpay/platform
Length of output: 11111
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Check output detail handling for comparison ==="
sed -n '112,130p' packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift
echo -e "\n=== Search for output isMine patterns ==="
rg 'outputs.append.*isMine' packages/swift-sdk/Sources/SwiftDashSDK/ --type swift -B 2 -A 2
echo -e "\n=== Look for Package.swift or dependency declarations ==="
find packages/swift-sdk -name "Package.swift" -o -name "*.podspec" | xargs cat 2>/dev/null | grep -A 20 "DashSDKFFI\|dependency" | head -40
echo -e "\n=== Check git for when DashSDKFFI was introduced ==="
git log --oneline --all -S "DashSDKFFI" -- packages/swift-sdk 2>/dev/null | head -10
echo -e "\n=== Search for any is_mine field usage anywhere in codebase ==="
rg 'is_mine|\.isMine\s*=' packages/swift-sdk/Sources/SwiftDashSDK/ --type swiftRepository: dashpay/platform
Length of output: 3455
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Search for FFI_OUTPUT_ROLE and similar input role constants ==="
rg 'FFI_OUTPUT_ROLE|FFI_INPUT_ROLE' packages/swift-sdk/ --type swift --type h
echo -e "\n=== Search for role field usage with input details ==="
rg 'input.*role|detail\.role' packages/swift-sdk/Sources/SwiftDashSDK/ --type swift -B 3 -A 3
echo -e "\n=== Look at the full getTransactions method around input/output handling ==="
sed -n '57,145p' packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swiftRepository: dashpay/platform
Length of output: 4849
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Check recent commits about input detail mapping ==="
git log --all --oneline --grep="input" -- packages/swift-sdk | head -15
echo -e "\n=== Check for any documentation about FFIInputDetail fields ==="
rg 'FFIInputDetail|input_detail.*struct' packages/ --type rust --type h -A 15 | head -80
echo -e "\n=== Look for rs-dashcore-ffi or FFI binding definitions ==="
find packages -name "*.rs" -path "*/ffi/*" | xargs grep -l "input_detail\|InputDetail" 2>/dev/null | head -5
echo -e "\n=== Check the Rust FFI crate for input/output detail definitions ==="
rg 'pub struct.*InputDetail|pub struct.*OutputDetail' packages/rs-sdk-ffi packages/rs-platform-wallet-ffi --type rust -A 10Repository: dashpay/platform
Length of output: 180
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== List FFI framework contents ==="
find packages/swift-sdk -name "DashSDKFFI.xcframework" -o -name "*.modulemap" -o -name "module.modulemap" 2>/dev/null | head -10
echo -e "\n=== Check for input detail in rust bindings broadly ==="
find packages -type f -name "*.rs" | xargs grep -l "input.*detail\|struct.*Detail" 2>/dev/null | grep -E "(ffi|binding)" | head -10
echo -e "\n=== Search in rs-sdk-ffi directory ==="
find packages/rs-sdk-ffi -type f -name "*.rs" | head -20
echo -e "\n=== Look for input_detail in any rust file ==="
rg 'input.*detail|InputDetail' packages/ --type rust --max-count 20
echo -e "\n=== Check if there's C header with FFIInputDetail ==="
find packages -name "*.h" | xargs grep -l "input_detail\|InputDetail" 2>/dev/nullRepository: dashpay/platform
Length of output: 152
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Check if FFIInputDetail is mentioned anywhere or similar patterns ==="
rg 'FFIInputDetail|FFIOutputDetail' packages/swift-sdk/ --type swift -B 2 -A 2
echo -e "\n=== Check commit that added output role mapping ==="
git log --all -p --grep="output.*role\|FFI_OUTPUT_ROLE" -- packages/swift-sdk | head -100
echo -e "\n=== Check latest commits to ManagedAccount.swift ==="
git log --oneline -- packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift | head -20
echo -e "\n=== Look at the specific commit that added input_details mapping ==="
git show 6015040bd:packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift 2>/dev/null | grep -A 20 "Convert input details" | head -25Repository: dashpay/platform
Length of output: 133
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Try to find what fields are accessed on input/output detail ==="
grep -n 'detail\.' packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift | grep -E "input|output" -A 5 -B 5
echo -e "\n=== Look at commit history for this file ==="
git log --oneline -20 packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift
echo -e "\n=== Check if there are any TODOs or FIXMEs related to isMine ==="
rg 'TODO|FIXME|XXX' packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift -B 2 -A 2
echo -e "\n=== Look at TxIO struct definition to understand the field ==="
rg 'struct TxIO|class TxIO' packages/swift-sdk/Sources/SwiftDashSDK/ -A 10 --type swiftRepository: dashpay/platform
Length of output: 832
Map input ownership from FFIInputDetail role field, matching output detail handling
Line 106 hardcodes isMine: false for all inputs, which will misclassify wallet-owned inputs in outgoing and internal transactions. This breaks sender/owner UI logic and contradicts the output detail handling at line 116, which correctly checks detail.role == FFI_OUTPUT_ROLE_RECEIVED || detail.role == FFI_OUTPUT_ROLE_CHANGE.
Update input mapping to check the role field if available on FFIInputDetail, or document why inputs lack ownership metadata if the field is not exposed:
Current code (lines 105-107)
for j in 0..<ffiTx.input_details_count {
let detail = inputsPtr.advanced(by: j).pointee
let address = detail.address != nil ? String(cString: detail.address) : ""
inputs.append(TxIO(address: address, amount: detail.value, isMine: false))
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift`
around lines 100 - 107, The input mapping currently hardcodes isMine: false in
ManagedAccount.swift when building inputs, causing misclassification; update the
loop that builds inputs (the section that iterates ffiTx.input_details and
appends TxIO) to inspect the FFIInputDetail.role field (analogous to the output
handling that checks detail.role == FFI_OUTPUT_ROLE_RECEIVED || detail.role ==
FFI_OUTPUT_ROLE_CHANGE) and set isMine = true when the role indicates the input
is wallet-owned, otherwise false; if FFIInputDetail does not expose a role
field, document that fact in a comment and request exposing ownership metadata
from the FFI so inputs can be classified properly.
Summary
TxIOstruct (address, amount, isMine) for transaction input/output recordsWalletTransactionwithinputs,outputs,txType,direction,instantSendLockedfields (all with defaults for backward compatibility)getTransactions()mapping to populate fromFFITransactionRecord'sinput_details,output_details,transaction_type,direction, andcontext.islock_dataMotivation
dashwallet-ios function - (transaction list migration from DashSync to SwiftDashSDK) needs these fields to display full transaction details. The FFI already delivers this data via
FFITransactionRecord— the Swift SDK was just dropping it on the floor.Dependencies
addressandvaluetoFFIOutputDetail). Without that PR, output addresses are empty strings — the rest works independently.Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes