-
Notifications
You must be signed in to change notification settings - Fork 250
sync main #3298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sync main #3298
Changes from all commits
7ec8f85
7988160
44ca2fa
51e04aa
af47946
bf8774c
ffe74db
a2237c1
55174f3
14b0157
6e867da
701d3cc
9bdee62
c9c3434
e5e0d86
f0a6b0d
4f93114
b033188
5ffab50
00d19ab
ae8eb92
6e83be9
d8eef4f
49d1756
e472aad
8c6fb84
909bf11
051ac42
19537e0
4bf37d5
6047895
fbd4db4
6a2237b
b9be4b8
f2d40bb
fb5738f
3d12c67
2ecaf56
812f939
5e35d03
d920efe
2c8c4c4
2bbe79a
e89068d
95104f6
193140f
7428040
cfaa180
89e62fc
257e0af
5bac9d1
514c1f2
9c4674c
9f2afdb
fc2f907
491e9f9
0494442
bb099db
5b416f3
9900372
02e3f2d
0c2eef2
24276e8
6614fad
dce1709
cf5c124
43a02dd
0f4bc96
4ff4a6e
bb03bdc
3f7703d
00ab6c7
27b7db2
7c79a2f
245d796
8c8bb2b
b9ef42b
b51ee27
e139c6b
d25676d
1742d1e
a54f065
922a0d0
c7e0a1e
1ade9f0
1312486
6f9a5bb
0a91838
2d82108
5252473
ebb3f74
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -406,7 +406,7 @@ | |
| "$(PROJECT_DIR)", | ||
| ); | ||
| MACOSX_DEPLOYMENT_TARGET = 15.0; | ||
| PRODUCT_BUNDLE_IDENTIFIER = com.komodoplatform.atomicdex; | ||
| PRODUCT_BUNDLE_IDENTIFIER = com.komodo.wallet; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainVerify bundle identifier change impact and readiness. Changing the iOS bundle identifier from Ensure the following are addressed:
Run the following script to check for hardcoded references to the old bundle identifier: Also verify the Android package name for consistency: Also applies to: 552-552, 587-587 🏁 Script executed: #!/bin/bash
# Search for hardcoded references to the old bundle identifier
echo "Searching for old bundle identifier references..."
rg -n "com\.komodoplatform\.atomicdex" --type-add 'config:*.{plist,entitlements,xcconfig}' --type config
echo -e "\nSearching in Dart/Flutter files..."
rg -n "com\.komodoplatform\.atomicdex" --type dart
echo -e "\nSearching in Swift/Objective-C files..."
rg -n "com\.komodoplatform\.atomicdex" --type swift --type objc
echo -e "\nSearching in configuration files..."
rg -n "com\.komodoplatform\.atomicdex" --glob '*.json' --glob '*.yaml' --glob '*.yml'Length of output: 280 🏁 Script executed: #!/bin/bash
# Check Android package name in build.gradle
echo "Checking Android package name..."
fd -e gradle -x grep -Hn "applicationId"Length of output: 115 🏁 Script executed: #!/bin/bash
# Check for any references to the new iOS bundle ID in Android or Web files
echo "Checking if new iOS bundle ID appears in Android/Web configs..."
rg -n "com\.komodo\.wallet" --glob '*.gradle' --glob '*.json' --glob '*.yaml'
echo -e "\nLooking for package name patterns in Android files..."
rg -n "package" ./android/app/build.gradle -A2 -B2
echo -e "\nChecking Web manifest structure..."
cat ./web/manifest.json 2>/dev/null | head -20Length of output: 221 🏁 Script executed: #!/bin/bash
# Find and inspect Android and Web configuration files
echo "=== Finding Android build.gradle ==="
fd build.gradle -x cat {}
echo -e "\n=== Checking web/manifest.json ==="
fd manifest.json -x cat {}
echo -e "\n=== Checking if new iOS bundle ID (com.komodo.wallet) appears anywhere in non-iOS configs ==="
rg -n "com\.komodo\.wallet"Length of output: 5338 Update Android and web configurations to match iOS bundle identifier change. The iOS bundle identifier has been successfully changed to Required fixes:
Additional concern: This is a breaking app identity change across platforms. Ensure a user data migration strategy exists (e.g., via App Groups, iCloud, or Firebase), and verify all infrastructure updates are ready (provisioning profiles, App Store Connect, certificates, Sign in with Apple, push notifications). Also applies to: 552-552, 587-587 |
||
| PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||
| SWIFT_VERSION = 5.0; | ||
|
|
@@ -549,7 +549,7 @@ | |
| "$(PROJECT_DIR)", | ||
| ); | ||
| MACOSX_DEPLOYMENT_TARGET = 15.0; | ||
| PRODUCT_BUNDLE_IDENTIFIER = com.komodoplatform.atomicdex; | ||
| PRODUCT_BUNDLE_IDENTIFIER = com.komodo.wallet; | ||
| PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||
| SWIFT_OPTIMIZATION_LEVEL = "-Onone"; | ||
|
|
@@ -584,7 +584,7 @@ | |
| "$(PROJECT_DIR)", | ||
| ); | ||
| MACOSX_DEPLOYMENT_TARGET = 15.0; | ||
| PRODUCT_BUNDLE_IDENTIFIER = com.komodoplatform.atomicdex; | ||
| PRODUCT_BUNDLE_IDENTIFIER = com.komodo.wallet; | ||
| PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||
| SWIFT_VERSION = 5.0; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,11 +28,11 @@ class BridgeValidator { | |
| required CoinsRepo coinsRepository, | ||
| required DexRepository dexRepository, | ||
| required KomodoDefiSdk sdk, | ||
| }) : _bloc = bloc, | ||
| _coinsRepo = coinsRepository, | ||
| _dexRepo = dexRepository, | ||
| _sdk = sdk, | ||
| _add = bloc.add; | ||
| }) : _bloc = bloc, | ||
| _coinsRepo = coinsRepository, | ||
| _dexRepo = dexRepository, | ||
| _sdk = sdk, | ||
| _add = bloc.add; | ||
|
|
||
| final BridgeBloc _bloc; | ||
| final CoinsRepo _coinsRepo; | ||
|
|
@@ -71,32 +71,32 @@ class BridgeValidator { | |
| } | ||
|
|
||
| DexFormError? _parsePreimageError( | ||
| DataFromService<TradePreimage, BaseError> preimageData) { | ||
| DataFromService<TradePreimage, BaseError> preimageData, | ||
| ) { | ||
| final BaseError? error = preimageData.error; | ||
|
|
||
| if (error is TradePreimageNotSufficientBalanceError) { | ||
| return _insufficientBalanceError( | ||
| Rational.parse(error.required), error.coin); | ||
| Rational.parse(error.required), | ||
| error.coin, | ||
| ); | ||
| } else if (error is TradePreimageNotSufficientBaseCoinBalanceError) { | ||
| return _insufficientBalanceError( | ||
| Rational.parse(error.required), error.coin); | ||
| } else if (error is TradePreimageTransportError) { | ||
| return DexFormError( | ||
| error: LocaleKeys.notEnoughBalanceForGasError.tr(), | ||
| Rational.parse(error.required), | ||
| error.coin, | ||
| ); | ||
| } else if (error is TradePreimageTransportError) { | ||
| return DexFormError(error: LocaleKeys.notEnoughBalanceForGasError.tr()); | ||
| } else if (error is TradePreimageVolumeTooLowError) { | ||
| return DexFormError( | ||
| error: LocaleKeys.lowTradeVolumeError | ||
| .tr(args: [formatAmt(double.parse(error.threshold)), error.coin]), | ||
| error: LocaleKeys.lowTradeVolumeError.tr( | ||
| args: [formatAmt(double.parse(error.threshold)), error.coin], | ||
| ), | ||
| ); | ||
| } else if (error != null) { | ||
| return DexFormError( | ||
| error: error.message, | ||
| ); | ||
| return DexFormError(error: error.message); | ||
| } else if (preimageData.data == null) { | ||
| return DexFormError( | ||
| error: LocaleKeys.somethingWrong.tr(), | ||
| ); | ||
| return DexFormError(error: LocaleKeys.somethingWrong.tr()); | ||
| } | ||
|
|
||
| return null; | ||
|
|
@@ -128,10 +128,15 @@ class BridgeValidator { | |
| _state.sellAmount, | ||
| ); | ||
| } catch (e, s) { | ||
| log(e.toString(), | ||
| trace: s, path: 'bridge_validator::_getPreimageData', isError: true); | ||
| log( | ||
| e.toString(), | ||
| trace: s, | ||
| path: 'bridge_validator::_getPreimageData', | ||
| isError: true, | ||
| ); | ||
| return DataFromService( | ||
| error: TextError(error: 'Failed to request trade preimage')); | ||
| error: TextError(error: 'Failed to request trade preimage'), | ||
| ); | ||
| } | ||
|
Comment on lines
+131
to
140
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Localize and preserve context in preimage fetch failure. Error text is hard-coded and loses localization. Also include a concise reason for better UX. - return DataFromService(
- error: TextError(error: 'Failed to request trade preimage'),
- );
+ return DataFromService(
+ error: TextError(
+ error: LocaleKeys.somethingWrong.tr(), // generic localized fallback
+ ),
+ );
🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
|
|
@@ -187,17 +192,17 @@ class BridgeValidator { | |
| if (availableBalance < maxOrderVolume && sellAmount > availableBalance) { | ||
| final Rational minAmount = maxRational([ | ||
| _state.minSellAmount ?? Rational.zero, | ||
| _state.bestOrder!.minVolume | ||
| _state.bestOrder!.minVolume, | ||
| ])!; | ||
|
|
||
| if (availableBalance < minAmount) { | ||
| _add(BridgeSetError( | ||
| _insufficientBalanceError(minAmount, _state.sellCoin!.abbr), | ||
| )); | ||
| _add( | ||
| BridgeSetError( | ||
| _insufficientBalanceError(minAmount, _state.sellCoin!.abbr), | ||
| ), | ||
| ); | ||
| } else { | ||
| _add(BridgeSetError( | ||
| _setMaxError(availableBalance), | ||
| )); | ||
| _add(BridgeSetError(_setMaxError(availableBalance))); | ||
| } | ||
|
|
||
| return false; | ||
|
|
@@ -218,9 +223,11 @@ class BridgeValidator { | |
| if (sellAmount < minAmount) { | ||
| final Rational available = _state.maxSellAmount ?? Rational.zero; | ||
| if (available < minAmount) { | ||
| _add(BridgeSetError( | ||
| _insufficientBalanceError(minAmount, _state.sellCoin!.abbr), | ||
| )); | ||
| _add( | ||
| BridgeSetError( | ||
| _insufficientBalanceError(minAmount, _state.sellCoin!.abbr), | ||
| ), | ||
| ); | ||
| } else { | ||
| _add(BridgeSetError(_setMinError(minAmount))); | ||
| } | ||
|
|
@@ -233,22 +240,17 @@ class BridgeValidator { | |
|
|
||
| Future<bool> _validateCoinAndParent(String abbr) async { | ||
| final coin = _sdk.getSdkAsset(abbr); | ||
| final enabledAssets = await _sdk.assets.getActivatedAssets(); | ||
| final isAssetEnabled = enabledAssets.contains(coin); | ||
| final activatedAssetIds = await _coinsRepo.getActivatedAssetIds(); | ||
| final parentId = coin.id.parentId; | ||
| final parent = _sdk.assets.available[parentId]; | ||
|
|
||
| if (!isAssetEnabled) { | ||
| if (!activatedAssetIds.contains(coin.id)) { | ||
| _add(BridgeSetError(_coinNotActiveError(coin.id.id))); | ||
| return false; | ||
| } | ||
|
|
||
| if (parent != null) { | ||
| final isParentEnabled = enabledAssets.contains(parent); | ||
| if (!isParentEnabled) { | ||
| _add(BridgeSetError(_coinNotActiveError(parent.id.id))); | ||
| return false; | ||
| } | ||
| if (parentId != null && !activatedAssetIds.contains(parentId)) { | ||
| _add(BridgeSetError(_coinNotActiveError(parentId.id))); | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
|
|
@@ -262,7 +264,8 @@ class BridgeValidator { | |
|
|
||
| final selectedOrderAddress = selectedOrder.address; | ||
| final asset = _sdk.getSdkAsset(selectedOrder.coin); | ||
| final ownPubkeys = await _sdk.pubkeys.getPubkeys(asset); | ||
| final cached = _sdk.pubkeys.lastKnown(asset.id); | ||
| final ownPubkeys = cached ?? await _sdk.pubkeys.getPubkeys(asset); | ||
| final ownAddresses = ownPubkeys.keys | ||
|
Comment on lines
+267
to
269
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Harden trading-with-self check against pubkeys fetch failures. A transient pubkeys error will currently abort validation. Catch and degrade to “not trading with self” while logging. - final cached = _sdk.pubkeys.lastKnown(asset.id);
- final ownPubkeys = cached ?? await _sdk.pubkeys.getPubkeys(asset);
+ final cached = _sdk.pubkeys.lastKnown(asset.id);
+ AssetPubkeys? ownPubkeys = cached;
+ if (ownPubkeys == null) {
+ try {
+ ownPubkeys = await _sdk.pubkeys.getPubkeys(asset);
+ } catch (e, s) {
+ log(
+ 'Failed to load pubkeys for self-trade check: $e',
+ trace: s,
+ path: 'bridge_validator::_checkTradeWithSelf',
+ isError: true,
+ );
+ return false; // Don’t block the user on this non-critical check
+ }
+ }🤖 Prompt for AI Agents |
||
| .where((pubkeyInfo) => pubkeyInfo.isActiveForSwap) | ||
| .map((e) => e.address) | ||
|
|
@@ -304,8 +307,9 @@ class BridgeValidator { | |
|
|
||
| DexFormError _setOrderMaxError(Rational maxAmount) { | ||
| return DexFormError( | ||
| error: LocaleKeys.dexMaxOrderVolume | ||
| .tr(args: [formatDexAmt(maxAmount), _state.sellCoin!.abbr]), | ||
| error: LocaleKeys.dexMaxOrderVolume.tr( | ||
| args: [formatDexAmt(maxAmount), _state.sellCoin!.abbr], | ||
| ), | ||
| type: DexFormErrorType.largerMaxSellVolume, | ||
| action: DexFormErrorAction( | ||
| text: LocaleKeys.setMax.tr(), | ||
|
|
@@ -318,8 +322,9 @@ class BridgeValidator { | |
|
|
||
| DexFormError _insufficientBalanceError(Rational required, String abbr) { | ||
| return DexFormError( | ||
| error: LocaleKeys.dexBalanceNotSufficientError | ||
| .tr(args: [abbr, formatDexAmt(required), abbr]), | ||
| error: LocaleKeys.dexBalanceNotSufficientError.tr( | ||
| args: [abbr, formatDexAmt(required), abbr], | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -341,20 +346,20 @@ class BridgeValidator { | |
| DexFormError _setMinError(Rational minAmount) { | ||
| return DexFormError( | ||
| type: DexFormErrorType.lessMinVolume, | ||
| error: LocaleKeys.dexMinSellAmountError | ||
| .tr(args: [formatDexAmt(minAmount), _state.sellCoin!.abbr]), | ||
| error: LocaleKeys.dexMinSellAmountError.tr( | ||
| args: [formatDexAmt(minAmount), _state.sellCoin!.abbr], | ||
| ), | ||
| action: DexFormErrorAction( | ||
| text: LocaleKeys.setMin.tr(), | ||
| callback: () async { | ||
| _add(BridgeSetSellAmount(minAmount)); | ||
| }), | ||
| text: LocaleKeys.setMin.tr(), | ||
| callback: () async { | ||
| _add(BridgeSetSellAmount(minAmount)); | ||
| }, | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| DexFormError _tradingWithSelfError() { | ||
| return DexFormError( | ||
| error: LocaleKeys.dexTradingWithSelfError.tr(), | ||
| ); | ||
| return DexFormError(error: LocaleKeys.dexTradingWithSelfError.tr()); | ||
| } | ||
|
|
||
| bool get _isSellCoinSelected => _state.sellCoin != null; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Remove
allow-top-navigation; enforce iframe URL allowlist to prevent escape and phishingAdd strict URL validation before assigning iframe src:
function _komodoSetIframeUrlFromParams() { const urlParam = _komodoGetUrlParameter('fiatUrl'); let targetUrl = null; if (urlParam) { try { targetUrl = atob(urlParam); // base64 decode the `url` parameter } catch (error) { console.error('Error decoding base64 url parameter', error); } } - if (targetUrl) { - document.getElementById('fiat-onramp-iframe').src = targetUrl; + if (targetUrl) { + try { + const urlObj = new URL(targetUrl); + const allowedHosts = [ + 'app.ramp.network', + 'app.demo.ramp.network', + 'komodo.banxa.com', + 'komodo.banxa-sandbox.com', + 'embed.bitrefill.com', + 'app.komodoplatform.com', + ]; + const isHttp = urlObj.protocol === 'https:' || urlObj.protocol === 'http:'; + const hostOk = allowedHosts.some(d => urlObj.hostname === d || urlObj.hostname.endsWith('.' + d)); + if (!isHttp || !hostOk) { + throw new Error('Blocked untrusted iframe origin: ' + urlObj.hostname); + } + document.getElementById('fiat-onramp-iframe').src = urlObj.toString(); + } catch (e) { + console.error('Invalid or disallowed targetUrl', e); + } } else { console.error('No URL parameter provided'); } }Optional hardening: restrict postMessage target origins instead of "*", if you can determine the parent’s origin.
Also applies to: 49-66