Skip to content

Commit

Permalink
Merge
Browse files Browse the repository at this point in the history
  • Loading branch information
tombeckenham committed Dec 16, 2024
1 parent ca377b7 commit dabcd94
Show file tree
Hide file tree
Showing 38 changed files with 565 additions and 223 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
"javascript.updateImportsOnFileMove.enabled": "always",
"typescript.updateImportsOnFileMove.enabled": "always",
"eslint.useFlatConfig": true,
"githubPullRequests.overrideDefaultBranch": "dev"
"githubPullRequests.overrideDefaultBranch": "dev",
"githubIssues.issueBranchTitle": "${issueNumber}-${sanitizedIssueTitle}"
}
2 changes: 1 addition & 1 deletion _raw/manifest/manifest.dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 3,
"name": "FlowWallet-dev",
"short_name": "__MSG_appName__",
"version": "2.6.2",
"version": "2.6.3",
"default_locale": "en",
"description": "__MSG_appDescription__",
"icons": {
Expand Down
2 changes: 1 addition & 1 deletion _raw/manifest/manifest.pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 3,
"name": "__MSG_appName__",
"short_name": "__MSG_appName__",
"version": "2.6.2",
"version": "2.6.3",
"default_locale": "en",
"description": "__MSG_appDescription__",
"icons": {
Expand Down
129 changes: 129 additions & 0 deletions build/analyze-dependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const webpackConfig = require('../webpack.config.js');

class DependencyAnalyzer {
constructor() {
this.dependencies = {
background: new Set(),
ui: new Set(),
content: new Set(),
shared: new Set(),
};
}

analyzeDependencies(stats) {
const modules = new Map();

// Use compilation.modules instead of chunk.getModules()
stats.compilation.modules.forEach((module) => {
if (!module.resource || !module.resource.includes('node_modules')) {
return;
}

const pkg = module.resource.split('node_modules/')[1].split('/')[0];
const chunks = Array.from(module.chunksIterable || []);

chunks.forEach((chunk) => {
const target = chunk.name?.includes('background')
? 'background'
: chunk.name?.includes('ui')
? 'ui'
: chunk.name?.includes('content')
? 'content'
: null;

if (target) {
if (!modules.has(pkg)) {
modules.set(pkg, new Set());
}
modules.get(pkg).add(target);
}
});
});

// Categorize dependencies
modules.forEach((targets, pkg) => {
if (targets.size > 1) {
this.dependencies.shared.add(pkg);
} else {
const [target] = targets;
this.dependencies[target].add(pkg);
}
});

return this;
}

generateReport() {
let report = '# Extension Dependencies Analysis\n\n';
report += `> Generated on ${new Date().toLocaleString()}\n\n`;

// Add summary
report += '## Summary\n\n';
Object.entries(this.dependencies).forEach(([target, deps]) => {
report += `- **${target}**: ${deps.size} packages\n`;
});
report += '\n';

// Add detailed lists
Object.entries(this.dependencies).forEach(([target, deps]) => {
report += `## ${target.charAt(0).toUpperCase() + target.slice(1)} Dependencies\n\n`;
if (deps.size === 0) {
report += '_No dependencies_\n\n';
} else {
Array.from(deps)
.sort()
.forEach((dep) => {
report += `- \`${dep}\`\n`;
});
report += '\n';
}
});

return report;
}
}

// Prepare build environment
console.log('Preparing build environment...');

// Copy manifest
fs.copyFileSync(
path.join(__dirname, '../_raw/manifest/manifest.dev.json'),
path.join(__dirname, '../_raw/manifest.json')
);

// Clean dist directory
const distPath = path.join(__dirname, '../dist');
if (!fs.existsSync(distPath)) {
fs.mkdirSync(distPath);
} else {
fs.rmSync(distPath, { recursive: true });
fs.mkdirSync(distPath);
}

// Copy _raw contents to dist
fs.cpSync(path.join(__dirname, '../_raw'), distPath, { recursive: true });

// Get webpack config using the same configuration as build:dev
const config = webpackConfig({ config: 'dev' });

// Run the analysis
console.log('Starting webpack build and analysis...');
const analyzer = new DependencyAnalyzer();

webpack(config, (err, stats) => {
if (err || stats.hasErrors()) {
console.error('Build failed:', err || stats.toString());
process.exit(1);
}

console.log('Build complete, analyzing dependencies...');
const report = analyzer.analyzeDependencies(stats).generateReport();

const reportPath = path.join(__dirname, '../extension-dependencies.md');
fs.writeFileSync(reportPath, report);
console.log(`Analysis complete! Check ${reportPath}`);
});
136 changes: 136 additions & 0 deletions build/analyze-imports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;

class ImportAnalyzer {
constructor() {
this.imports = new Map(); // package -> Set of files using it
this.packageLocations = {
background: new Set(),
ui: new Set(),
content: new Set(),
};
}

analyzeFile(filePath) {
const content = fs.readFileSync(filePath, 'utf-8');
const relativePath = path.relative(process.cwd(), filePath);

try {
const ast = parser.parse(content, {
sourceType: 'module',
plugins: ['typescript', 'jsx'],
});

traverse(ast, {
ImportDeclaration: (path) => {
const importPath = path.node.source.value;

// Only analyze external packages (not relative imports)
if (!importPath.startsWith('.') && !importPath.startsWith('@/')) {
const packageName = importPath.startsWith('@')
? importPath.split('/').slice(0, 2).join('/')
: importPath.split('/')[0];

if (!this.imports.has(packageName)) {
this.imports.set(packageName, new Set());
}
this.imports.get(packageName).add(relativePath);

// Categorize by location
if (relativePath.includes('background/')) {
this.packageLocations.background.add(packageName);
} else if (relativePath.includes('ui/')) {
this.packageLocations.ui.add(packageName);
} else if (relativePath.includes('content/')) {
this.packageLocations.content.add(packageName);
}
}
},
CallExpression(path) {
// Check for require() calls
if (path.node.callee.name === 'require') {
const arg = path.node.arguments[0];
if (arg && arg.type === 'StringLiteral') {
const importPath = arg.value;
if (!importPath.startsWith('.') && !importPath.startsWith('@/')) {
const packageName = importPath.startsWith('@')
? importPath.split('/').slice(0, 2).join('/')
: importPath.split('/')[0];

if (!this.imports.has(packageName)) {
this.imports.set(packageName, new Set());
}
this.imports.get(packageName).add(relativePath);

// Categorize by location
if (relativePath.includes('background/')) {
this.packageLocations.background.add(packageName);
} else if (relativePath.includes('ui/')) {
this.packageLocations.ui.add(packageName);
} else if (relativePath.includes('content/')) {
this.packageLocations.content.add(packageName);
}
}
}
}
},
});
} catch (error) {
console.warn(`Failed to parse ${relativePath}:`, error.message);
}
}

generateReport() {
let report = '# Dependency Usage Analysis\n\n';
report += `> Generated on ${new Date().toLocaleString()}\n\n`;

// Summary by location
report += '## Package Usage by Location\n\n';
Object.entries(this.packageLocations).forEach(([location, packages]) => {
report += `### ${location.charAt(0).toUpperCase() + location.slice(1)}\n\n`;
Array.from(packages)
.sort()
.forEach((pkg) => {
const usageCount = this.imports.get(pkg).size;
report += `- \`${pkg}\` (${usageCount} ${usageCount === 1 ? 'file' : 'files'})\n`;
});
report += '\n';
});

// Detailed usage
report += '## Detailed Package Usage\n\n';
Array.from(this.imports.entries())
.sort(([a], [b]) => a.localeCompare(b))
.forEach(([pkg, files]) => {
report += `### \`${pkg}\`\n\n`;
Array.from(files)
.sort()
.forEach((file) => {
report += `- ${file}\n`;
});
report += '\n';
});

return report;
}
}

// Run the analysis
console.log('Starting import analysis...');
const analyzer = new ImportAnalyzer();

// Find all TypeScript and JavaScript files
const files = glob.sync('src/**/*.{ts,tsx,js,jsx}', {
ignore: ['**/node_modules/**', '**/dist/**'],
});

files.forEach((file) => {
analyzer.analyzeFile(file);
});

const report = analyzer.generateReport();
fs.writeFileSync('dependency-usage.md', report);
console.log('Analysis complete! Check dependency-usage.md');
36 changes: 17 additions & 19 deletions src/background/controller/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { getAuth } from 'firebase/auth';
import web3, { TransactionError } from 'web3';

import eventBus from '@/eventBus';
import { type FeatureFlags } from '@/shared/types/feature-types';
import { isValidEthereumAddress, withPrefix } from '@/shared/utils/address';
import { getHashAlgo, getSignAlgo } from '@/shared/utils/algo';
// eslint-disable-next-line import/order,no-restricted-imports
// eslint-disable-next-line no-restricted-imports
import { findAddressWithNetwork } from '@/ui/utils/modules/findAddressWithPK';
import {
keyringService,
Expand Down Expand Up @@ -54,7 +55,7 @@ import DisplayKeyring from '../service/keyring/display';
import type { NFTData, NFTModel, StorageInfo, WalletResponse } from '../service/networkModel';
import type { ConnectedSite } from '../service/permission';
import type { Account } from '../service/preference';
import { StorageEvaluator } from '../service/storage-evaluator';
import { type EvaluateStorageResult, StorageEvaluator } from '../service/storage-evaluator';
import type { UserInfoStore } from '../service/user';
import defaultConfig from '../utils/defaultConfig.json';
import { getStoragedAccount } from '../utils/getStoragedAccount';
Expand Down Expand Up @@ -3875,6 +3876,10 @@ export class WalletController extends BaseController {
}
};

getFeatureFlags = async (): Promise<FeatureFlags> => {
return openapiService.getFeatureFlags();
};

allowLilicoPay = async (): Promise<boolean> => {
const isFreeGasFeeKillSwitch = await storage.get('freeGas');
const isFreeGasFeeEnabled = await storage.get('lilicoPayer');
Expand Down Expand Up @@ -4072,24 +4077,17 @@ export class WalletController extends BaseController {
transferAmount?: number; // amount in coins
coin?: string; // coin name
movingBetweenEVMAndFlow?: boolean; // are we moving between EVM and Flow?
} = {}): Promise<{
isStorageSufficient: boolean;
isStorageSufficientAfterAction: boolean;
storageInfo: StorageInfo;
}> => {
} = {}): Promise<EvaluateStorageResult> => {
const address = await this.getCurrentAddress();
const { isStorageSufficient, isStorageSufficientAfterAction, storageInfo } =
await this.storageEvaluator.evaluateStorage(
address!,
transferAmount,
coin,
movingBetweenEVMAndFlow
);
return {
isStorageSufficient,
isStorageSufficientAfterAction,
storageInfo,
};
const isFreeGasFeeEnabled = await this.allowLilicoPay();
const result = await this.storageEvaluator.evaluateStorage(
address!,
transferAmount,
coin,
movingBetweenEVMAndFlow,
isFreeGasFeeEnabled
);
return result;
};

// Tracking stuff
Expand Down
14 changes: 13 additions & 1 deletion src/background/service/conditions-evaluator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { NewsConditionType } from '@/shared/types/news-types';

import { userWalletService } from '../service';
import { StorageEvaluator } from '../service/storage-evaluator';

import type { NewsConditionType } from './networkModel';
import openapi from './openapi';

const CURRENT_VERSION = chrome.runtime.getManifest().version;
Expand All @@ -25,6 +26,11 @@ class ConditionsEvaluator {
if (!currentAddress) return false;
return this.evaluateStorageCondition(currentAddress);
}
case 'insufficientBalance': {
const currentAddress = userWalletService.getCurrentAddress();
if (!currentAddress) return false;
return this.evaluateBalanceCondition(currentAddress);
}

case 'unknown':
default:
Expand Down Expand Up @@ -66,6 +72,12 @@ class ConditionsEvaluator {
const { isStorageSufficient } = await storageEvaluator.evaluateStorage(address);
return !isStorageSufficient;
}

async evaluateBalanceCondition(address: string): Promise<boolean> {
const storageEvaluator = new StorageEvaluator();
const { isBalanceSufficient } = await storageEvaluator.evaluateStorage(address);
return !isBalanceSufficient;
}
}

export default new ConditionsEvaluator();
Loading

0 comments on commit dabcd94

Please sign in to comment.