@solana-mobile/dapp-store-cli 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/CliSetup.js +55 -45
- package/lib/CliUtils.js +13 -6
- package/lib/commands/ValidateCommand.js +0 -3
- package/lib/commands/create/CreateCliApp.js +1 -3
- package/lib/commands/create/CreateCliPublisher.js +6 -4
- package/lib/commands/create/CreateCliRelease.js +37 -16
- package/lib/commands/publish/PublishCliSubmit.js +16 -3
- package/lib/commands/publish/PublishCliUpdate.js +16 -3
- package/lib/config/PublishDetails.js +269 -13
- package/lib/generated/config_obj.json +1 -1
- package/lib/package.json +5 -4
- package/lib/prebuild_schema/publishing_source.yaml +9 -1
- package/package.json +5 -4
- package/src/CliSetup.ts +32 -14
- package/src/CliUtils.ts +15 -7
- package/src/commands/ValidateCommand.ts +0 -4
- package/src/commands/create/CreateCliApp.ts +1 -0
- package/src/commands/create/CreateCliPublisher.ts +3 -0
- package/src/commands/create/CreateCliRelease.ts +33 -9
- package/src/commands/publish/PublishCliSubmit.ts +11 -1
- package/src/commands/publish/PublishCliUpdate.ts +10 -1
- package/src/config/PublishDetails.ts +119 -13
- package/src/prebuild_schema/publishing_source.yaml +9 -1
|
@@ -219,6 +219,7 @@ import { Constants, showMessage } from "../CliUtils.js";
|
|
|
219
219
|
import util from "util";
|
|
220
220
|
import { imageSize } from "image-size";
|
|
221
221
|
import { exec } from "child_process";
|
|
222
|
+
import getVideoDimensions from "get-video-dimensions";
|
|
222
223
|
var runImgSize = util.promisify(imageSize);
|
|
223
224
|
var runExec = util.promisify(exec);
|
|
224
225
|
var AaptPrefixes = {
|
|
@@ -265,7 +266,7 @@ export var loadPublishDetails = function() {
|
|
|
265
266
|
}();
|
|
266
267
|
export var loadPublishDetailsWithChecks = function() {
|
|
267
268
|
var _ref = _async_to_generator(function() {
|
|
268
|
-
var buildToolsDir, _config_publisher_media_find, _config_publisher_media, _config_app_media_find, _config_app_media, _config_release_media_find, _config_release_media, _config_release_media1, config, apkEntry, apkPath, _, publisherIcon, iconPath, iconBuffer, appIcon, iconPath1, iconBuffer1, releaseIcon, iconPath2, screenshots, googlePkg, pkgCompare;
|
|
269
|
+
var buildToolsDir, _config_publisher_media_find, _config_publisher_media, _config_app_media_find, _config_app_media, _config_release_media_find, _config_release_media, _config_release_media1, _config_release_media2, config, apkEntry, apkPath, _, publisherIcon, iconPath, iconBuffer, appIcon, iconPath1, iconBuffer1, releaseIcon, iconPath2, screenshots, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, item, mediaPath, err, videos, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, video, mediaPath1, err, googlePkg, pkgCompare;
|
|
269
270
|
var _arguments = arguments;
|
|
270
271
|
return _ts_generator(this, function(_state) {
|
|
271
272
|
switch(_state.label){
|
|
@@ -363,16 +364,145 @@ export var loadPublishDetailsWithChecks = function() {
|
|
|
363
364
|
throw new Error("Please specify at least one media entry of type icon in your configuration file");
|
|
364
365
|
}
|
|
365
366
|
config.release.media.forEach(function(item) {
|
|
366
|
-
var
|
|
367
|
-
if (!fs.existsSync(
|
|
368
|
-
throw new Error("
|
|
367
|
+
var mediaPath = path.join(process.cwd(), item.uri);
|
|
368
|
+
if (!fs.existsSync(mediaPath)) {
|
|
369
|
+
throw new Error("File doesnt exist: ".concat(item.uri, "."));
|
|
370
|
+
}
|
|
371
|
+
if (item.purpose == "screenshot" && !checkImageExtension(mediaPath)) {
|
|
372
|
+
throw new Error("Please ensure the file ".concat(item.uri, " is a jpeg, png, or webp file."));
|
|
373
|
+
}
|
|
374
|
+
if (item.purpose == "video" && !checkVideoExtension(mediaPath)) {
|
|
375
|
+
throw new Error("Please ensure the file ".concat(item.uri, " is a mp4."));
|
|
369
376
|
}
|
|
370
377
|
});
|
|
371
378
|
screenshots = (_config_release_media1 = config.release.media) === null || _config_release_media1 === void 0 ? void 0 : _config_release_media1.filter(function(asset) {
|
|
372
379
|
return asset.purpose === "screenshot";
|
|
373
380
|
});
|
|
374
|
-
|
|
375
|
-
|
|
381
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
382
|
+
_state.label = 12;
|
|
383
|
+
case 12:
|
|
384
|
+
_state.trys.push([
|
|
385
|
+
12,
|
|
386
|
+
17,
|
|
387
|
+
18,
|
|
388
|
+
19
|
|
389
|
+
]);
|
|
390
|
+
_iterator = screenshots[Symbol.iterator]();
|
|
391
|
+
_state.label = 13;
|
|
392
|
+
case 13:
|
|
393
|
+
if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
|
|
394
|
+
3,
|
|
395
|
+
16
|
|
396
|
+
];
|
|
397
|
+
item = _step.value;
|
|
398
|
+
mediaPath = path.join(process.cwd(), item.uri);
|
|
399
|
+
return [
|
|
400
|
+
4,
|
|
401
|
+
checkScreenshotSize(mediaPath)
|
|
402
|
+
];
|
|
403
|
+
case 14:
|
|
404
|
+
if (_state.sent()) {
|
|
405
|
+
throw new Error("Screenshot ".concat(mediaPath, " must be at least 1080px in width and height."));
|
|
406
|
+
}
|
|
407
|
+
_state.label = 15;
|
|
408
|
+
case 15:
|
|
409
|
+
_iteratorNormalCompletion = true;
|
|
410
|
+
return [
|
|
411
|
+
3,
|
|
412
|
+
13
|
|
413
|
+
];
|
|
414
|
+
case 16:
|
|
415
|
+
return [
|
|
416
|
+
3,
|
|
417
|
+
19
|
|
418
|
+
];
|
|
419
|
+
case 17:
|
|
420
|
+
err = _state.sent();
|
|
421
|
+
_didIteratorError = true;
|
|
422
|
+
_iteratorError = err;
|
|
423
|
+
return [
|
|
424
|
+
3,
|
|
425
|
+
19
|
|
426
|
+
];
|
|
427
|
+
case 18:
|
|
428
|
+
try {
|
|
429
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
430
|
+
_iterator.return();
|
|
431
|
+
}
|
|
432
|
+
} finally{
|
|
433
|
+
if (_didIteratorError) {
|
|
434
|
+
throw _iteratorError;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return [
|
|
438
|
+
7
|
|
439
|
+
];
|
|
440
|
+
case 19:
|
|
441
|
+
videos = (_config_release_media2 = config.release.media) === null || _config_release_media2 === void 0 ? void 0 : _config_release_media2.filter(function(asset) {
|
|
442
|
+
return asset.purpose === "video";
|
|
443
|
+
});
|
|
444
|
+
_iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
445
|
+
_state.label = 20;
|
|
446
|
+
case 20:
|
|
447
|
+
_state.trys.push([
|
|
448
|
+
20,
|
|
449
|
+
25,
|
|
450
|
+
26,
|
|
451
|
+
27
|
|
452
|
+
]);
|
|
453
|
+
_iterator1 = videos[Symbol.iterator]();
|
|
454
|
+
_state.label = 21;
|
|
455
|
+
case 21:
|
|
456
|
+
if (!!(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done)) return [
|
|
457
|
+
3,
|
|
458
|
+
24
|
|
459
|
+
];
|
|
460
|
+
video = _step1.value;
|
|
461
|
+
mediaPath1 = path.join(process.cwd(), video.uri);
|
|
462
|
+
return [
|
|
463
|
+
4,
|
|
464
|
+
checkVideoSize(mediaPath1)
|
|
465
|
+
];
|
|
466
|
+
case 22:
|
|
467
|
+
if (_state.sent()) {
|
|
468
|
+
throw new Error("Video ".concat(mediaPath1, " must be at least 720px in width and height."));
|
|
469
|
+
}
|
|
470
|
+
_state.label = 23;
|
|
471
|
+
case 23:
|
|
472
|
+
_iteratorNormalCompletion1 = true;
|
|
473
|
+
return [
|
|
474
|
+
3,
|
|
475
|
+
21
|
|
476
|
+
];
|
|
477
|
+
case 24:
|
|
478
|
+
return [
|
|
479
|
+
3,
|
|
480
|
+
27
|
|
481
|
+
];
|
|
482
|
+
case 25:
|
|
483
|
+
err = _state.sent();
|
|
484
|
+
_didIteratorError1 = true;
|
|
485
|
+
_iteratorError1 = err;
|
|
486
|
+
return [
|
|
487
|
+
3,
|
|
488
|
+
27
|
|
489
|
+
];
|
|
490
|
+
case 26:
|
|
491
|
+
try {
|
|
492
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
493
|
+
_iterator1.return();
|
|
494
|
+
}
|
|
495
|
+
} finally{
|
|
496
|
+
if (_didIteratorError1) {
|
|
497
|
+
throw _iteratorError1;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return [
|
|
501
|
+
7
|
|
502
|
+
];
|
|
503
|
+
case 27:
|
|
504
|
+
if (screenshots.length + videos.length < 4) {
|
|
505
|
+
throw new Error("At least 4 screenshots or videos are required for publishing a new release. Found only ".concat(screenshots.length + videos.length));
|
|
376
506
|
}
|
|
377
507
|
validateLocalizableResources(config);
|
|
378
508
|
googlePkg = config.solana_mobile_dapp_publisher_portal.google_store_package;
|
|
@@ -423,6 +553,10 @@ var checkImageExtension = function(uri) {
|
|
|
423
553
|
var fileExt = path.extname(uri).toLowerCase();
|
|
424
554
|
return fileExt == ".png" || fileExt == ".jpg" || fileExt == ".jpeg" || fileExt == ".webp";
|
|
425
555
|
};
|
|
556
|
+
var checkVideoExtension = function(uri) {
|
|
557
|
+
var fileExt = path.extname(uri).toLowerCase();
|
|
558
|
+
return fileExt == ".mp4";
|
|
559
|
+
};
|
|
426
560
|
/**
|
|
427
561
|
* We need to pre-check some things in the localized resources before we move forward
|
|
428
562
|
*/ var validateLocalizableResources = function(config) {
|
|
@@ -468,6 +602,52 @@ var checkIconDimensions = function() {
|
|
|
468
602
|
return _ref.apply(this, arguments);
|
|
469
603
|
};
|
|
470
604
|
}();
|
|
605
|
+
var checkScreenshotSize = function() {
|
|
606
|
+
var _ref = _async_to_generator(function(imagePath) {
|
|
607
|
+
var size, _size_width, _size_height;
|
|
608
|
+
return _ts_generator(this, function(_state) {
|
|
609
|
+
switch(_state.label){
|
|
610
|
+
case 0:
|
|
611
|
+
return [
|
|
612
|
+
4,
|
|
613
|
+
runImgSize(imagePath)
|
|
614
|
+
];
|
|
615
|
+
case 1:
|
|
616
|
+
size = _state.sent();
|
|
617
|
+
return [
|
|
618
|
+
2,
|
|
619
|
+
((_size_width = size === null || size === void 0 ? void 0 : size.width) !== null && _size_width !== void 0 ? _size_width : 0) < 1080 || ((_size_height = size === null || size === void 0 ? void 0 : size.height) !== null && _size_height !== void 0 ? _size_height : 0) < 1080
|
|
620
|
+
];
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
});
|
|
624
|
+
return function checkScreenshotSize(imagePath) {
|
|
625
|
+
return _ref.apply(this, arguments);
|
|
626
|
+
};
|
|
627
|
+
}();
|
|
628
|
+
var checkVideoSize = function() {
|
|
629
|
+
var _ref = _async_to_generator(function(imagePath) {
|
|
630
|
+
var size, _size_width, _size_height;
|
|
631
|
+
return _ts_generator(this, function(_state) {
|
|
632
|
+
switch(_state.label){
|
|
633
|
+
case 0:
|
|
634
|
+
return [
|
|
635
|
+
4,
|
|
636
|
+
getVideoDimensions(imagePath)
|
|
637
|
+
];
|
|
638
|
+
case 1:
|
|
639
|
+
size = _state.sent();
|
|
640
|
+
return [
|
|
641
|
+
2,
|
|
642
|
+
((_size_width = size === null || size === void 0 ? void 0 : size.width) !== null && _size_width !== void 0 ? _size_width : 0) < 720 || ((_size_height = size === null || size === void 0 ? void 0 : size.height) !== null && _size_height !== void 0 ? _size_height : 0) < 720
|
|
643
|
+
];
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
});
|
|
647
|
+
return function checkVideoSize(imagePath) {
|
|
648
|
+
return _ref.apply(this, arguments);
|
|
649
|
+
};
|
|
650
|
+
}();
|
|
471
651
|
var getAndroidDetails = function() {
|
|
472
652
|
var _ref = _async_to_generator(function(aaptDir, apkPath) {
|
|
473
653
|
var stdout, appPackage, versionCode, versionName, minSdk, permissions, locales, isDebuggable, _locales_values, localeArray, localesSrc, _appPackage_, _minSdk_, _versionCode_, _versionName_, _tmp, e;
|
|
@@ -490,7 +670,9 @@ var getAndroidDetails = function() {
|
|
|
490
670
|
versionCode = new RegExp(AaptPrefixes.verCodePrefix + AaptPrefixes.quoteRegex).exec(stdout);
|
|
491
671
|
versionName = new RegExp(AaptPrefixes.verNamePrefix + AaptPrefixes.quoteRegex).exec(stdout);
|
|
492
672
|
minSdk = new RegExp(AaptPrefixes.sdkPrefix + AaptPrefixes.quoteRegex).exec(stdout);
|
|
493
|
-
permissions = _to_consumable_array(stdout.matchAll(/uses-permission: name='(.*)'/g))
|
|
673
|
+
permissions = _to_consumable_array(stdout.matchAll(/uses-permission: name='(.*)'/g)).flatMap(function(permission) {
|
|
674
|
+
return permission[1];
|
|
675
|
+
});
|
|
494
676
|
locales = new RegExp(AaptPrefixes.localePrefix + AaptPrefixes.quoteNonLazyRegex).exec(stdout);
|
|
495
677
|
isDebuggable = new RegExp(AaptPrefixes.debuggableApkPrefix).exec(stdout);
|
|
496
678
|
if (isDebuggable != null) {
|
|
@@ -503,9 +685,19 @@ var getAndroidDetails = function() {
|
|
|
503
685
|
"en-US"
|
|
504
686
|
].concat(localesSrc.split("' '").slice(1));
|
|
505
687
|
}
|
|
688
|
+
if (permissions.includes("android.permission.INSTALL_PACKAGES") || permissions.includes("android.permission.DELETE_PACKAGES")) {
|
|
689
|
+
showMessage("App requests system app install/delete permission", "Your app requests system install/delete permission which is managed by Solana dApp Store.\nThis app will be not approved for listing on Solana dApp Store.", "error");
|
|
690
|
+
}
|
|
691
|
+
if (permissions.includes("android.permission.REQUEST_INSTALL_PACKAGES") || permissions.includes("android.permission.REQUEST_DELETE_PACKAGES")) {
|
|
692
|
+
showMessage("App requests install or delete permission", "App will be subject to additional security reviews for listing on Solana dApp Store and processing time may be beyond regular review time", "warning");
|
|
693
|
+
}
|
|
694
|
+
if (permissions.includes("com.solanamobile.seedvault.ACCESS_SEED_VAULT")) {
|
|
695
|
+
showMessage("App requests Seed Vault permission", "If this is not a wallet application, your app maybe rejected from listing on Solana dApp Store.", "warning");
|
|
696
|
+
}
|
|
506
697
|
if (localeArray.length >= 60) {
|
|
507
698
|
showMessage("The bundle apk claims supports for following locales", "Claim for supported locales::\n" + localeArray + "\nIf this release does not support all these locales the release may be rejected" + "\nSee details at https://developer.android.com/guide/topics/resources/multilingual-support#design for configuring the supported locales", "warning");
|
|
508
699
|
}
|
|
700
|
+
checkAbis(apkPath);
|
|
509
701
|
_tmp = {
|
|
510
702
|
android_package: (_appPackage_ = appPackage === null || appPackage === void 0 ? void 0 : appPackage[1]) !== null && _appPackage_ !== void 0 ? _appPackage_ : "",
|
|
511
703
|
min_sdk: parseInt((_minSdk_ = minSdk === null || minSdk === void 0 ? void 0 : minSdk[1]) !== null && _minSdk_ !== void 0 ? _minSdk_ : "0", 10),
|
|
@@ -519,9 +711,7 @@ var getAndroidDetails = function() {
|
|
|
519
711
|
case 2:
|
|
520
712
|
return [
|
|
521
713
|
2,
|
|
522
|
-
(_tmp.cert_fingerprint = _state.sent(), _tmp.permissions = permissions.
|
|
523
|
-
return permission[1];
|
|
524
|
-
}), _tmp.locales = localeArray, _tmp)
|
|
714
|
+
(_tmp.cert_fingerprint = _state.sent(), _tmp.permissions = permissions, _tmp.locales = localeArray, _tmp)
|
|
525
715
|
];
|
|
526
716
|
case 3:
|
|
527
717
|
e = _state.sent();
|
|
@@ -545,6 +735,70 @@ var getAndroidDetails = function() {
|
|
|
545
735
|
return _ref.apply(this, arguments);
|
|
546
736
|
};
|
|
547
737
|
}();
|
|
738
|
+
var checkAbis = function() {
|
|
739
|
+
var _ref = _async_to_generator(function(apkPath) {
|
|
740
|
+
var stdout, amV7libs, x86libs, x8664libs, messages, e;
|
|
741
|
+
return _ts_generator(this, function(_state) {
|
|
742
|
+
switch(_state.label){
|
|
743
|
+
case 0:
|
|
744
|
+
_state.trys.push([
|
|
745
|
+
0,
|
|
746
|
+
2,
|
|
747
|
+
,
|
|
748
|
+
3
|
|
749
|
+
]);
|
|
750
|
+
return [
|
|
751
|
+
4,
|
|
752
|
+
runExec("zipinfo -s ".concat(apkPath, " | grep .so$"))
|
|
753
|
+
];
|
|
754
|
+
case 1:
|
|
755
|
+
stdout = _state.sent().stdout;
|
|
756
|
+
amV7libs = _to_consumable_array(stdout.matchAll(/lib\/armeabi-v7a\/(.*)/g)).flatMap(function(permission) {
|
|
757
|
+
return permission[1];
|
|
758
|
+
});
|
|
759
|
+
x86libs = _to_consumable_array(stdout.matchAll(/lib\/x86\/(.*)/g)).flatMap(function(permission) {
|
|
760
|
+
return permission[1];
|
|
761
|
+
});
|
|
762
|
+
x8664libs = _to_consumable_array(stdout.matchAll(/lib\/x86_64\/(.*)/g)).flatMap(function(permission) {
|
|
763
|
+
return permission[1];
|
|
764
|
+
});
|
|
765
|
+
if (amV7libs.length > 0 || x86libs.length > 0 || x8664libs.length > 0) {
|
|
766
|
+
messages = [
|
|
767
|
+
"Solana dApp Store only supports arm64-v8a abi.",
|
|
768
|
+
"Your apk file contains following unsupported abis"
|
|
769
|
+
].concat(_to_consumable_array(amV7libs.length > 0 ? [
|
|
770
|
+
"\narmeabi-v7a:\n" + amV7libs
|
|
771
|
+
] : []), _to_consumable_array(x86libs.length > 0 ? [
|
|
772
|
+
"\nx86:\n" + x86libs
|
|
773
|
+
] : []), _to_consumable_array(x8664libs.length > 0 ? [
|
|
774
|
+
"\nx86_64:\n" + x8664libs
|
|
775
|
+
] : []), [
|
|
776
|
+
"\n\nAlthough your app works fine on Saga, these library files are unused and increase the size of apk file making the download and update time longer for your app.",
|
|
777
|
+
"\n\nSee https://developer.android.com/games/optimize/64-bit#build-with-64-bit for how to optimize your app."
|
|
778
|
+
]).join("\n");
|
|
779
|
+
showMessage("Unsupported files found in apk", messages, "warning");
|
|
780
|
+
}
|
|
781
|
+
return [
|
|
782
|
+
3,
|
|
783
|
+
3
|
|
784
|
+
];
|
|
785
|
+
case 2:
|
|
786
|
+
e = _state.sent();
|
|
787
|
+
return [
|
|
788
|
+
3,
|
|
789
|
+
3
|
|
790
|
+
];
|
|
791
|
+
case 3:
|
|
792
|
+
return [
|
|
793
|
+
2
|
|
794
|
+
];
|
|
795
|
+
}
|
|
796
|
+
});
|
|
797
|
+
});
|
|
798
|
+
return function checkAbis(apkPath) {
|
|
799
|
+
return _ref.apply(this, arguments);
|
|
800
|
+
};
|
|
801
|
+
}();
|
|
548
802
|
export var extractCertFingerprint = function() {
|
|
549
803
|
var _ref = _async_to_generator(function(aaptDir, apkPath) {
|
|
550
804
|
var stdout, regex, match;
|
|
@@ -579,11 +833,11 @@ export var extractCertFingerprint = function() {
|
|
|
579
833
|
}();
|
|
580
834
|
export var writeToPublishDetails = function() {
|
|
581
835
|
var _ref = _async_to_generator(function(param) {
|
|
582
|
-
var publisher, app, release, currentConfig, _publisher_address, _app_address, _release_address, newConfig;
|
|
836
|
+
var publisher, app, release, lastSubmittedVersionOnChain, lastUpdatedVersionOnStore, currentConfig, _publisher_address, _app_address, _release_address, newConfig;
|
|
583
837
|
return _ts_generator(this, function(_state) {
|
|
584
838
|
switch(_state.label){
|
|
585
839
|
case 0:
|
|
586
|
-
publisher = param.publisher, app = param.app, release = param.release;
|
|
840
|
+
publisher = param.publisher, app = param.app, release = param.release, lastSubmittedVersionOnChain = param.lastSubmittedVersionOnChain, lastUpdatedVersionOnStore = param.lastUpdatedVersionOnStore;
|
|
587
841
|
return [
|
|
588
842
|
4,
|
|
589
843
|
loadPublishDetailsWithChecks()
|
|
@@ -602,7 +856,9 @@ export var writeToPublishDetails = function() {
|
|
|
602
856
|
release: _object_spread_props(_object_spread({}, currentConfig.release), {
|
|
603
857
|
address: (_release_address = release === null || release === void 0 ? void 0 : release.address) !== null && _release_address !== void 0 ? _release_address : currentConfig.release.address
|
|
604
858
|
}),
|
|
605
|
-
solana_mobile_dapp_publisher_portal: currentConfig.solana_mobile_dapp_publisher_portal
|
|
859
|
+
solana_mobile_dapp_publisher_portal: currentConfig.solana_mobile_dapp_publisher_portal,
|
|
860
|
+
lastSubmittedVersionOnChain: lastSubmittedVersionOnChain !== null && lastSubmittedVersionOnChain !== void 0 ? lastSubmittedVersionOnChain : currentConfig.lastSubmittedVersionOnChain,
|
|
861
|
+
lastUpdatedVersionOnStore: lastUpdatedVersionOnStore !== null && lastUpdatedVersionOnStore !== void 0 ? lastUpdatedVersionOnStore : currentConfig.lastUpdatedVersionOnStore
|
|
606
862
|
};
|
|
607
863
|
fs.writeFileSync(Constants.getConfigFilePath(), dump(newConfig, {
|
|
608
864
|
lineWidth: -1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"publisher":{"name":"<<YOUR_PUBLISHER_NAME>>","address":"","website":"<<URL_OF_PUBLISHER_WEBSITE>>","email":"<<EMAIL_ADDRESS_TO_CONTACT_PUBLISHER>>","media":[{"purpose":"icon","uri":"<<RELATIVE_PATH_TO_PUBLISHER_ICON>>"}]},"app":{"name":"<<APP_NAME>>","address":"","android_package":"<<ANDROID_PACKAGE_NAME>>","urls":{"license_url":"<<URL_OF_APP_LICENSE_OR_TERMS_OF_SERVICE>>","copyright_url":"<<URL_OF_COPYRIGHT_DETAILS_FOR_APP>>","privacy_policy_url":"<<URL_OF_APP_PRIVACY_POLICY>>","website":"<<URL_OF_APP_WEBSITE>>"},"media":[{"purpose":"icon","uri":"<<RELATIVE_PATH_TO_APP_ICON>>"}]},"release":{"address":"","media":[{"purpose":"icon","uri":"<<RELATIVE_PATH_TO_RELEASE_ICON>>"},{"purpose":"screenshot","uri":"<<
|
|
1
|
+
{"publisher":{"name":"<<YOUR_PUBLISHER_NAME>>","address":"","website":"<<URL_OF_PUBLISHER_WEBSITE>>","email":"<<EMAIL_ADDRESS_TO_CONTACT_PUBLISHER>>","media":[{"purpose":"icon","uri":"<<RELATIVE_PATH_TO_PUBLISHER_ICON>>"}]},"app":{"name":"<<APP_NAME>>","address":"","android_package":"<<ANDROID_PACKAGE_NAME>>","urls":{"license_url":"<<URL_OF_APP_LICENSE_OR_TERMS_OF_SERVICE>>","copyright_url":"<<URL_OF_COPYRIGHT_DETAILS_FOR_APP>>","privacy_policy_url":"<<URL_OF_APP_PRIVACY_POLICY>>","website":"<<URL_OF_APP_WEBSITE>>"},"media":[{"purpose":"icon","uri":"<<RELATIVE_PATH_TO_APP_ICON>>"}]},"release":{"address":"","media":[{"purpose":"icon","uri":"<<RELATIVE_PATH_TO_RELEASE_ICON>>"},{"purpose":"screenshot","uri":"<<RELATIVE_PATH_TO_SCREENSHOT1>>"},{"purpose":"screenshot","uri":"<<RELATIVE_PATH_TO_SCREENSHOT2>>"},{"purpose":"screenshot","uri":"<<RELATIVE_PATH_TO_SCREENSHOT3>>"},{"purpose":"screenshot","uri":"<<RELATIVE_PATH_TO_SCREENSHOT4>>"},{"purpose":"video","uri":"<<RELATIVE_PATH_TO_VIDEO1>>"}],"files":[{"purpose":"install","uri":"<<RELATIVE_PATH_TO_APK>>"}],"catalog":{"en-US":{"name":"<<APP_NAME>>","short_description":"<<SHORT_APP_DESCRIPTION>>","long_description":"<<LONG_APP_DESCRIPTION>>","new_in_version":"<<WHATS_NEW_IN_THIS_VERSION>>","saga_features":"<<ANY_FEATURES_ONLY_AVAILBLE_WHEN_RUNNING_ON_SAGA>>"}}},"solana_mobile_dapp_publisher_portal":{"google_store_package":"<<ANDROID_PACKAGE_NAME_OF_GOOGLE_PLAY_STORE_VERSION_IF_DIFFERENT>>","testing_instructions":"<<TESTING_INSTRUCTIONS>>"}}
|
package/lib/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana-mobile/dapp-store-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@metaplex-foundation/js": "0.18.3",
|
|
38
37
|
"@jest/globals": "^29.5.0",
|
|
39
38
|
"@jest/types": "^29.5.0",
|
|
39
|
+
"@metaplex-foundation/js": "0.20.0",
|
|
40
40
|
"@swc/jest": "^0.2.26",
|
|
41
41
|
"@types/commander": "^2.12.2",
|
|
42
42
|
"@types/debug": "^4.1.7",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@aws-sdk/client-s3": "^3.321.1",
|
|
55
|
-
"@metaplex-foundation/js-plugin-aws": "^0.
|
|
56
|
-
"@solana-mobile/dapp-store-publishing-tools": "workspace:0.
|
|
55
|
+
"@metaplex-foundation/js-plugin-aws": "^0.20.0",
|
|
56
|
+
"@solana-mobile/dapp-store-publishing-tools": "workspace:0.9.0",
|
|
57
57
|
"@solana/web3.js": "1.68.0",
|
|
58
58
|
"@types/semver": "^7.3.13",
|
|
59
59
|
"ajv": "^8.11.0",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"dotenv": "^16.0.3",
|
|
65
65
|
"esm": "^3.2.25",
|
|
66
66
|
"generate-schema": "^2.6.0",
|
|
67
|
+
"get-video-dimensions": "^1.0.0",
|
|
67
68
|
"image-size": "^1.0.2",
|
|
68
69
|
"js-yaml": "^4.1.0",
|
|
69
70
|
"semver": "^7.3.8",
|
|
@@ -24,7 +24,15 @@ release:
|
|
|
24
24
|
- purpose: icon
|
|
25
25
|
uri: <<RELATIVE_PATH_TO_RELEASE_ICON>>
|
|
26
26
|
- purpose: screenshot
|
|
27
|
-
uri: <<
|
|
27
|
+
uri: <<RELATIVE_PATH_TO_SCREENSHOT1>>
|
|
28
|
+
- purpose: screenshot
|
|
29
|
+
uri: <<RELATIVE_PATH_TO_SCREENSHOT2>>
|
|
30
|
+
- purpose: screenshot
|
|
31
|
+
uri: <<RELATIVE_PATH_TO_SCREENSHOT3>>
|
|
32
|
+
- purpose: screenshot
|
|
33
|
+
uri: <<RELATIVE_PATH_TO_SCREENSHOT4>>
|
|
34
|
+
- purpose: video
|
|
35
|
+
uri: <<RELATIVE_PATH_TO_VIDEO1>>
|
|
28
36
|
files:
|
|
29
37
|
- purpose: install
|
|
30
38
|
uri: <<RELATIVE_PATH_TO_APK>>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana-mobile/dapp-store-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@metaplex-foundation/js": "0.18.3",
|
|
31
30
|
"@jest/globals": "^29.5.0",
|
|
32
31
|
"@jest/types": "^29.5.0",
|
|
32
|
+
"@metaplex-foundation/js": "0.20.0",
|
|
33
33
|
"@swc/jest": "^0.2.26",
|
|
34
34
|
"@types/commander": "^2.12.2",
|
|
35
35
|
"@types/debug": "^4.1.7",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@aws-sdk/client-s3": "^3.321.1",
|
|
48
|
-
"@metaplex-foundation/js-plugin-aws": "^0.
|
|
49
|
-
"@solana-mobile/dapp-store-publishing-tools": "0.
|
|
48
|
+
"@metaplex-foundation/js-plugin-aws": "^0.20.0",
|
|
49
|
+
"@solana-mobile/dapp-store-publishing-tools": "0.9.0",
|
|
50
50
|
"@solana/web3.js": "1.68.0",
|
|
51
51
|
"@types/semver": "^7.3.13",
|
|
52
52
|
"ajv": "^8.11.0",
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"dotenv": "^16.0.3",
|
|
58
58
|
"esm": "^3.2.25",
|
|
59
59
|
"generate-schema": "^2.6.0",
|
|
60
|
+
"get-video-dimensions": "^1.0.0",
|
|
60
61
|
"image-size": "^1.0.2",
|
|
61
62
|
"js-yaml": "^4.1.0",
|
|
62
63
|
"semver": "^7.3.8",
|
package/src/CliSetup.ts
CHANGED
|
@@ -14,7 +14,8 @@ import {
|
|
|
14
14
|
dryRunSuccessMessage,
|
|
15
15
|
generateNetworkSuffix,
|
|
16
16
|
parseKeypair,
|
|
17
|
-
showMessage
|
|
17
|
+
showMessage,
|
|
18
|
+
showNetworkWarningIfApplicable
|
|
18
19
|
} from "./CliUtils.js";
|
|
19
20
|
import { LAMPORTS_PER_SOL } from "@solana/web3.js"
|
|
20
21
|
import * as dotenv from "dotenv";
|
|
@@ -49,6 +50,7 @@ function resolveBuildToolsPath(buildToolsPath: string | undefined) {
|
|
|
49
50
|
*/
|
|
50
51
|
function latestReleaseMessage() {
|
|
51
52
|
const messages = [
|
|
53
|
+
`- App details page now supports video files. (mp4 file format only and minimum resolution 720p)`,
|
|
52
54
|
`- priority fee has been updated to ${Constants.DEFAULT_PRIORITY_FEE} lamports = ${Constants.DEFAULT_PRIORITY_FEE / LAMPORTS_PER_SOL} SOL. To adjust this value use param "-p" or "--priority-fee-lamports"`,
|
|
53
55
|
`- At least 4 screenshots are now required to update or release a new app`,
|
|
54
56
|
`- App icons should be exactly 512x512.`
|
|
@@ -104,6 +106,7 @@ export const createPublisherCliCmd = createCliCmd
|
|
|
104
106
|
.option("-p, --priority-fee-lamports <priority-fee-lamports>", "Priority Fee lamports")
|
|
105
107
|
.action(async ({ keypair, url, dryRun, storageConfig, priorityFeeLamports }) => {
|
|
106
108
|
await tryWithErrorMessage(async () => {
|
|
109
|
+
showNetworkWarningIfApplicable(url)
|
|
107
110
|
latestReleaseMessage();
|
|
108
111
|
await checkForSelfUpdate();
|
|
109
112
|
|
|
@@ -141,6 +144,7 @@ export const createAppCliCmd = createCliCmd
|
|
|
141
144
|
.option("-p, --priority-fee-lamports <priority-fee-lamports>", "Priority Fee lamports")
|
|
142
145
|
.action(async ({ publisherMintAddress, keypair, url, dryRun, storageConfig, priorityFeeLamports }) => {
|
|
143
146
|
await tryWithErrorMessage(async () => {
|
|
147
|
+
showNetworkWarningIfApplicable(url)
|
|
144
148
|
latestReleaseMessage();
|
|
145
149
|
await checkForSelfUpdate();
|
|
146
150
|
|
|
@@ -194,6 +198,7 @@ export const createReleaseCliCmd = createCliCmd
|
|
|
194
198
|
.option("-p, --priority-fee-lamports <priority-fee-lamports>", "Priority Fee lamports")
|
|
195
199
|
.action(async ({ appMintAddress, keypair, url, dryRun, buildToolsPath, storageConfig, priorityFeeLamports }) => {
|
|
196
200
|
await tryWithErrorMessage(async () => {
|
|
201
|
+
showNetworkWarningIfApplicable(url)
|
|
197
202
|
latestReleaseMessage();
|
|
198
203
|
await checkForSelfUpdate();
|
|
199
204
|
|
|
@@ -310,7 +315,7 @@ publishCommand
|
|
|
310
315
|
}) => {
|
|
311
316
|
await tryWithErrorMessage(async () => {
|
|
312
317
|
await checkForSelfUpdate();
|
|
313
|
-
|
|
318
|
+
checkSubmissionNetwork(url);
|
|
314
319
|
|
|
315
320
|
const config = await loadPublishDetails(Constants.getConfigFilePath());
|
|
316
321
|
|
|
@@ -320,15 +325,28 @@ publishCommand
|
|
|
320
325
|
|
|
321
326
|
const signer = parseKeypair(keypair);
|
|
322
327
|
if (signer) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
328
|
+
if (config.lastUpdatedVersionOnStore != null && config.lastSubmittedVersionOnChain.address != null) {
|
|
329
|
+
await publishUpdateCommand({
|
|
330
|
+
appMintAddress: appMintAddress,
|
|
331
|
+
releaseMintAddress: releaseMintAddress,
|
|
332
|
+
signer: signer,
|
|
333
|
+
url: url,
|
|
334
|
+
dryRun: dryRun,
|
|
335
|
+
compliesWithSolanaDappStorePolicies: compliesWithSolanaDappStorePolicies,
|
|
336
|
+
requestorIsAuthorized: requestorIsAuthorized,
|
|
337
|
+
critical: false,
|
|
338
|
+
});
|
|
339
|
+
} else {
|
|
340
|
+
await publishSubmitCommand({
|
|
341
|
+
appMintAddress: appMintAddress,
|
|
342
|
+
releaseMintAddress: releaseMintAddress,
|
|
343
|
+
signer: signer,
|
|
344
|
+
url: url,
|
|
345
|
+
dryRun: dryRun,
|
|
346
|
+
compliesWithSolanaDappStorePolicies: compliesWithSolanaDappStorePolicies,
|
|
347
|
+
requestorIsAuthorized: requestorIsAuthorized,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
332
350
|
|
|
333
351
|
if (dryRun) {
|
|
334
352
|
dryRunSuccessMessage()
|
|
@@ -384,7 +402,7 @@ publishCommand
|
|
|
384
402
|
}) => {
|
|
385
403
|
await tryWithErrorMessage(async () => {
|
|
386
404
|
await checkForSelfUpdate();
|
|
387
|
-
|
|
405
|
+
checkSubmissionNetwork(url);
|
|
388
406
|
|
|
389
407
|
const config = await loadPublishDetails(Constants.getConfigFilePath())
|
|
390
408
|
|
|
@@ -454,7 +472,7 @@ publishCommand
|
|
|
454
472
|
}) => {
|
|
455
473
|
await tryWithErrorMessage(async () => {
|
|
456
474
|
await checkForSelfUpdate();
|
|
457
|
-
|
|
475
|
+
checkSubmissionNetwork(url);
|
|
458
476
|
|
|
459
477
|
const config = await loadPublishDetails(Constants.getConfigFilePath())
|
|
460
478
|
|
|
@@ -517,7 +535,7 @@ publishCommand
|
|
|
517
535
|
) => {
|
|
518
536
|
await tryWithErrorMessage(async () => {
|
|
519
537
|
await checkForSelfUpdate();
|
|
520
|
-
|
|
538
|
+
checkSubmissionNetwork(url);
|
|
521
539
|
|
|
522
540
|
const config = await loadPublishDetails(Constants.getConfigFilePath())
|
|
523
541
|
|
package/src/CliUtils.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Connection } from "@solana/web3.js";
|
|
|
3
3
|
import { Keypair, PublicKey } from "@solana/web3.js";
|
|
4
4
|
import debugModule from "debug";
|
|
5
5
|
import {
|
|
6
|
-
|
|
6
|
+
IrysStorageDriver,
|
|
7
7
|
keypairIdentity,
|
|
8
8
|
Metaplex,
|
|
9
9
|
} from "@metaplex-foundation/js";
|
|
@@ -18,7 +18,7 @@ import { awsStorage } from "@metaplex-foundation/js-plugin-aws";
|
|
|
18
18
|
import { S3StorageManager } from "./config/index.js";
|
|
19
19
|
|
|
20
20
|
export class Constants {
|
|
21
|
-
static CLI_VERSION = "0.
|
|
21
|
+
static CLI_VERSION = "0.9.0";
|
|
22
22
|
static CONFIG_FILE_NAME = "config.yaml";
|
|
23
23
|
static DEFAULT_RPC_DEVNET = "https://api.devnet.solana.com";
|
|
24
24
|
static DEFAULT_PRIORITY_FEE = 500000;
|
|
@@ -42,7 +42,7 @@ export const checkForSelfUpdate = async () => {
|
|
|
42
42
|
latestVer.minor > currentVer.minor
|
|
43
43
|
) {
|
|
44
44
|
throw new Error(
|
|
45
|
-
|
|
45
|
+
`Please update to the latest version of the dApp Store CLI before proceeding.\nCurrent version is ${currentVer.raw}\nLatest version is ${latestVer.raw}`
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
48
|
};
|
|
@@ -117,6 +117,14 @@ export const dryRunSuccessMessage = () => {
|
|
|
117
117
|
showMessage("Dry run", "Dry run was successful", "standard")
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
export const showNetworkWarningIfApplicable = (rpcUrl: string) => {
|
|
121
|
+
if (isDevnet(rpcUrl)) {
|
|
122
|
+
showMessage("Devnet Mode", "Running on Devnet", "warning")
|
|
123
|
+
} else if (isTestnet(rpcUrl)) {
|
|
124
|
+
showMessage("Testnet Mode", "Running on Testnet", "warning")
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
120
128
|
export const showMessage = (
|
|
121
129
|
titleMessage = "",
|
|
122
130
|
contentMessage = "",
|
|
@@ -167,16 +175,16 @@ export const getMetaplexInstance = (
|
|
|
167
175
|
const bucketPlugin = awsStorage(awsClient, s3Mgr.s3Config.bucketName);
|
|
168
176
|
metaplex.use(bucketPlugin);
|
|
169
177
|
} else {
|
|
170
|
-
const
|
|
171
|
-
? new
|
|
178
|
+
const irysStorageDriver = isDevnet
|
|
179
|
+
? new IrysStorageDriver(metaplex, {
|
|
172
180
|
address: "https://turbo.ardrive.dev",
|
|
173
181
|
providerUrl: Constants.DEFAULT_RPC_DEVNET,
|
|
174
182
|
})
|
|
175
|
-
: new
|
|
183
|
+
: new IrysStorageDriver(metaplex, {
|
|
176
184
|
address: "https://turbo.ardrive.io",
|
|
177
185
|
});
|
|
178
186
|
|
|
179
|
-
metaplex.storage().setDriver(
|
|
187
|
+
metaplex.storage().setDriver(irysStorageDriver);
|
|
180
188
|
}
|
|
181
189
|
|
|
182
190
|
metaplex.storage().setDriver(
|