Skip to content

Commit

Permalink
Showing 11 changed files with 260 additions and 249 deletions.
8 changes: 1 addition & 7 deletions lib/blocs/create_manifest/create_manifest_cubit.dart
Original file line number Diff line number Diff line change
@@ -223,13 +223,7 @@ class CreateManifestCubit extends Cubit<CreateManifestState> {
bundle.blob,
wallet,
);

// Add tips to bundle tx
final bundleTip = await _pst.getPSTFee(bundleTx.reward);
bundleTx
..addTag(TipType.tagName, TipType.dataUpload)
..setTarget(await _pst.getWeightedPstHolder())
..setQuantity(bundleTip);
await _pst.addCommunityTipToTx(bundleTx);

final totalCost = bundleTx.reward + bundleTx.quantity;

1 change: 1 addition & 0 deletions lib/blocs/drives/drives_cubit.dart
Original file line number Diff line number Diff line change
@@ -72,6 +72,7 @@ class DrivesCubit extends Cubit<DrivesState> {

void selectDrive(String driveId) {
final canCreateNewDrive = _profileCubit.state is ProfileLoggedIn;

final state = this.state is DrivesLoadSuccess
? (this.state as DrivesLoadSuccess).copyWith(selectedDriveId: driveId)
: DrivesLoadSuccess(
51 changes: 5 additions & 46 deletions lib/blocs/upload/cost_estimate.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import 'package:ardrive/blocs/upload/models/upload_plan.dart';
import 'package:ardrive/blocs/upload/upload_handles/bundle_upload_handle.dart';
import 'package:ardrive/blocs/upload/upload_handles/file_v2_upload_handle.dart';
import 'package:ardrive/entities/entity.dart';
import 'package:ardrive/services/arweave/arweave.dart';
import 'package:ardrive/services/pst/pst.dart';
import 'package:arweave/arweave.dart';
import 'package:arweave/utils.dart';
import 'package:package_info_plus/package_info_plus.dart';

final minimumPstTip = BigInt.from(10000000);

class CostEstimate {
/// The cost to upload the data, in AR.
@@ -25,15 +21,11 @@ class CostEstimate {
/// The sum of the upload cost and fees.
final BigInt totalCost;

/// The [Transaction] that pays `pstFee` to a random PST holder. (Only for v2 transaction uploads)
final Transaction? v2FilesFeeTx;

CostEstimate._create({
required this.arUploadCost,
required this.pstFee,
required this.totalCost,
this.usdUploadCost,
this.v2FilesFeeTx,
});

static Future<CostEstimate> create({
@@ -43,6 +35,7 @@ class CostEstimate {
required Wallet wallet,
}) async {
final _v2FileUploadHandles = uploadPlan.fileV2UploadHandles;

final dataItemsCost = await estimateCostOfAllBundles(
bundleUploadHandles: uploadPlan.bundleUploadHandles,
arweaveService: arweaveService,
@@ -52,60 +45,26 @@ class CostEstimate {
arweaveService: arweaveService);

final bundlePstFee = await pstService.getPSTFee(dataItemsCost);
final v2FilesPstFee = v2FilesUploadCost <= BigInt.zero
? BigInt.zero
: await pstService.getPSTFee(v2FilesUploadCost);

Transaction? v2FilesFeeTx;
if (_v2FileUploadHandles.isNotEmpty) {
v2FilesFeeTx = await prepareAndSignV2FilesTipTx(
arweaveService: arweaveService,
pstService: pstService,
wallet: wallet,
v2FilesUploadCost: v2FilesUploadCost,
);
}
final v2FilesPstFee = (v2FilesFeeTx?.quantity ?? BigInt.zero);
final totalCost =
v2FilesUploadCost + dataItemsCost + bundlePstFee + v2FilesPstFee;

final arUploadCost = winstonToAr(totalCost);
final usdUploadCost = await arweaveService
.getArUsdConversionRate()
.then((conversionRate) => double.parse(arUploadCost) * conversionRate);

return CostEstimate._create(
totalCost: totalCost,
arUploadCost: arUploadCost,
pstFee: v2FilesPstFee + bundlePstFee,
usdUploadCost: usdUploadCost,
v2FilesFeeTx: v2FilesFeeTx,
);
}

static Future<Transaction?> prepareAndSignV2FilesTipTx({
required ArweaveService arweaveService,
required PstService pstService,
required Wallet wallet,
required v2FilesUploadCost,
}) async {
if (v2FilesUploadCost <= BigInt.zero) {
return null;
}
final packageInfo = await PackageInfo.fromPlatform();
final pstFee = await pstService.getPSTFee(v2FilesUploadCost);
final quantity = pstFee > minimumPstTip ? pstFee : minimumPstTip;

final feeTx = await arweaveService.client.transactions.prepare(
Transaction(
target: await pstService.getWeightedPstHolder(),
quantity: quantity,
),
wallet,
)
..addApplicationTags(version: packageInfo.version)
..addTag('Type', 'fee')
..addTag(TipType.tagName, TipType.dataUpload);
await feeTx.sign(wallet);
return feeTx;
}

static Future<BigInt> estimateCostOfAllBundles({
required List<BundleUploadHandle> bundleUploadHandles,
required ArweaveService arweaveService,
9 changes: 1 addition & 8 deletions lib/blocs/upload/upload_cubit.dart
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@ part 'upload_state.dart';

final privateFileSizeLimit = 104857600;
final publicFileSizeLimit = 1.25 * math.pow(10, 9);
final minimumPstTip = BigInt.from(10000000);
final filesNamesToExclude = ['.DS_Store'];

class UploadCubit extends Cubit<UploadState> {
@@ -294,10 +293,6 @@ class UploadCubit extends Cubit<UploadState> {
),
);

if (costEstimate.v2FilesFeeTx != null) {
await _arweave.postTx(costEstimate.v2FilesFeeTx!);
}

// Upload Bundles
for (var bundleHandle in uploadPlan.bundleUploadHandles) {
await bundleHandle.prepareAndSignBundleTransaction(
@@ -318,9 +313,7 @@ class UploadCubit extends Cubit<UploadState> {
// Upload V2 Files
for (final uploadHandle in uploadPlan.fileV2UploadHandles.values) {
await uploadHandle.prepareAndSignTransactions(
arweaveService: _arweave,
wallet: profile.wallet,
);
arweaveService: _arweave, wallet: profile.wallet, pstService: _pst);
await uploadHandle.writeFileEntityToDatabase(
driveDao: _driveDao,
);
10 changes: 4 additions & 6 deletions lib/blocs/upload/upload_handles/bundle_upload_handle.dart
Original file line number Diff line number Diff line change
@@ -61,13 +61,11 @@ class BundleUploadHandle implements UploadHandle {
wallet,
);

// Add tips to bundle tx
final bundleTip = await pstService.getPSTFee(bundleTx.reward);
bundleTx
..addTag(TipType.tagName, TipType.dataUpload)
..setTarget(await pstService.getWeightedPstHolder())
..setQuantity(bundleTip);
await pstService.addCommunityTipToTx(bundleTx);

await bundleTx.sign(wallet);

// Write entities to database
folderDataItemUploadHandles.forEach((folder) async {
await folder.writeFolderToDatabase(driveDao: driveDao);
});
12 changes: 8 additions & 4 deletions lib/blocs/upload/upload_handles/file_v2_upload_handle.dart
Original file line number Diff line number Diff line change
@@ -52,8 +52,11 @@ class FileV2UploadHandle implements UploadHandle {
});
}

Future<void> prepareAndSignTransactions(
{required ArweaveService arweaveService, required Wallet wallet}) async {
Future<void> prepareAndSignTransactions({
required ArweaveService arweaveService,
required Wallet wallet,
required PstService pstService,
}) async {
final packageInfo = await PackageInfo.fromPlatform();

final fileData = await file.readAsBytes();
@@ -62,9 +65,10 @@ class FileV2UploadHandle implements UploadHandle {
? await createEncryptedTransaction(fileData, fileKey!)
: Transaction.withBlobData(data: fileData),
wallet,
);
)
..addApplicationTags(version: packageInfo.version);

dataTx.addApplicationTags(version: packageInfo.version);
await pstService.addCommunityTipToTx(dataTx);

// Don't include the file's Content-Type tag if it is meant to be private.
if (!isPrivate) {
372 changes: 197 additions & 175 deletions lib/components/app_drawer/app_drawer.dart

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
@@ -1115,6 +1115,26 @@
}
}
},
"insufficientFundsForCreateADrive": "You do not have sufficient funds to create a Drive at this time. Please go to the top up page to add funds to your account.",
"@insufficientFundsForCreateADrive": {
"description": "Show that needs funds to create a Drive"
},
"insufficientFundsForCreateAFolder": "You do not have sufficient funds to create a Folder at this time. Please go to the top up page to add funds to your account.",
"@insufficientFundsForCreateADrive": {
"description": "Show that needs funds to create a Folder"
},
"insufficientFundsForCreateAManifest": "You do not have sufficient funds to create a Manifest at this time. Please go to the top up page to add funds to your account.",
"@insufficientFundsForCreateAManifest": {
"description": "Show that needs funds to create a Manifest"
},
"insufficientFundsForUploadFiles": "You do not have sufficient funds to upload Files at this time. Please go to the top up page to add funds to your account.",
"@insufficientFundsForUploadFiles": {
"description": "Show that needs funds to upload files"
},
"insufficientFundsForUploadFolders": "You do not have sufficient funds to upload Folders at this time. Please go to the top up page to add funds to your account.",
"@insufficientFundsForUploadFolders": {
"description": "Show that needs funds to upload folders"
},
"conflictingNameFound": "Conflicting name was found",
"@conflictingNameFound": {
"description": "There is a non-manifest entity with the same name"
1 change: 1 addition & 0 deletions lib/pages/app_router_delegate.dart
Original file line number Diff line number Diff line change
@@ -116,6 +116,7 @@ class AppRouterDelegate extends RouterDelegate<AppRoutePath>
if (state is DrivesLoadSuccess) {
shellPage =
!state.hasNoDrives ? DriveDetailPage() : NoDrivesPage();
driveId = state.selectedDriveId;
}

shellPage ??= const SizedBox();
19 changes: 19 additions & 0 deletions lib/services/pst/pst.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import 'package:arweave/arweave.dart';

import '../services.dart';
import 'implementations/pst_web.dart'
if (dart.library.io) 'implementations/pst_stub.dart' as implementation;

export 'enums.dart';

final minimumPstTip = BigInt.from(10000000);

class PstService {
/// Returns the fee percentage of the app PST as a decimal percentage.
Future<double> getPstFeePercentage() => implementation.getPstFeePercentage();
@@ -12,6 +17,14 @@ class PstService {
implementation.getWeightedPstHolder();

Future<BigInt> getPSTFee(BigInt uploadCost) async {
final pstFee = await _getPSTFee(uploadCost);
if (pstFee > minimumPstTip) {
return pstFee;
}
return minimumPstTip;
}

Future<BigInt> _getPSTFee(BigInt uploadCost) async {
return await implementation
.getPstFeePercentage()
.then((feePercentage) =>
@@ -21,4 +34,10 @@ class PstService {
.catchError((_) => BigInt.zero,
test: (err) => err is UnimplementedError);
}

Future<void> addCommunityTipToTx(Transaction tx) async {
tx.addTag(TipType.tagName, TipType.dataUpload);
tx.setTarget(await getWeightedPstHolder());
tx.setQuantity(await getPSTFee(tx.reward));
}
}
6 changes: 3 additions & 3 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: ardrive
description: Secure, permanent storage

publish_to: "none"
publish_to: 'none'

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
@@ -13,10 +13,10 @@ publish_to: "none"
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.14.1
version: 1.15.0

environment:
sdk: ">=2.13.0 <3.0.0"
sdk: '>=2.13.0 <3.0.0'

dependencies:
flutter:

0 comments on commit 79bf783

Please sign in to comment.