@solana-mobile/dapp-store-cli 0.10.0 → 0.12.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 +468 -568
- package/lib/CliUtils.js +18 -33
- package/lib/__tests__/CliSetupTest.js +4 -27
- package/lib/commands/ValidateCommand.js +15 -40
- package/lib/commands/create/CreateCliApp.js +18 -30
- package/lib/commands/create/CreateCliRelease.js +24 -27
- package/lib/commands/create/index.js +0 -1
- package/lib/commands/publish/PublishCliRemove.js +11 -19
- package/lib/commands/publish/PublishCliSubmit.js +11 -19
- package/lib/commands/publish/PublishCliSupport.js +11 -19
- package/lib/commands/publish/PublishCliUpdate.js +11 -19
- package/lib/commands/utils.js +6 -14
- package/lib/config/PublishDetails.js +138 -259
- package/lib/generated/config_obj.json +1 -1
- package/lib/generated/config_schema.json +1 -1
- package/lib/index.js +6 -14
- package/lib/package.json +2 -2
- package/lib/prebuild_schema/publishing_source.yaml +32 -32
- package/lib/upload/CachedStorageDriver.js +13 -19
- package/package.json +2 -2
- package/src/CliSetup.ts +5 -54
- package/src/CliUtils.ts +5 -11
- package/src/__tests__/CliSetupTest.ts +8 -43
- package/src/commands/ValidateCommand.ts +0 -20
- package/src/commands/create/CreateCliApp.ts +1 -8
- package/src/commands/create/CreateCliRelease.ts +10 -1
- package/src/commands/create/index.ts +0 -1
- package/src/commands/publish/PublishCliRemove.ts +1 -2
- package/src/commands/publish/PublishCliSubmit.ts +1 -2
- package/src/commands/publish/PublishCliSupport.ts +1 -2
- package/src/commands/publish/PublishCliUpdate.ts +1 -2
- package/src/config/PublishDetails.ts +30 -58
- package/src/prebuild_schema/publishing_source.yaml +32 -32
- package/lib/commands/create/CreateCliPublisher.js +0 -237
- package/src/commands/create/CreateCliPublisher.ts +0 -87
|
@@ -3,7 +3,6 @@ import { createApp } from "@solana-mobile/dapp-store-publishing-tools";
|
|
|
3
3
|
import {
|
|
4
4
|
Connection,
|
|
5
5
|
Keypair,
|
|
6
|
-
PublicKey,
|
|
7
6
|
} from "@solana/web3.js";
|
|
8
7
|
|
|
9
8
|
import {
|
|
@@ -17,14 +16,12 @@ const createAppNft = async (
|
|
|
17
16
|
{
|
|
18
17
|
appDetails,
|
|
19
18
|
connection,
|
|
20
|
-
publisherMintAddress,
|
|
21
19
|
publisher,
|
|
22
20
|
storageParams,
|
|
23
21
|
priorityFeeLamports,
|
|
24
22
|
}: {
|
|
25
23
|
appDetails: App;
|
|
26
24
|
connection: Connection;
|
|
27
|
-
publisherMintAddress: string;
|
|
28
25
|
publisher: Keypair;
|
|
29
26
|
storageParams: string;
|
|
30
27
|
priorityFeeLamports: number;
|
|
@@ -36,7 +33,6 @@ const createAppNft = async (
|
|
|
36
33
|
const metaplex = getMetaplexInstance(connection, publisher, storageParams);
|
|
37
34
|
const txBuilder = await createApp(
|
|
38
35
|
{
|
|
39
|
-
publisherMintAddress: new PublicKey(publisherMintAddress),
|
|
40
36
|
mintAddress,
|
|
41
37
|
appDetails,
|
|
42
38
|
priorityFeeLamports
|
|
@@ -55,7 +51,6 @@ const createAppNft = async (
|
|
|
55
51
|
};
|
|
56
52
|
|
|
57
53
|
type CreateAppCommandInput = {
|
|
58
|
-
publisherMintAddress: string;
|
|
59
54
|
signer: Keypair;
|
|
60
55
|
url: string;
|
|
61
56
|
dryRun?: boolean;
|
|
@@ -67,7 +62,6 @@ export const createAppCommand = async ({
|
|
|
67
62
|
signer,
|
|
68
63
|
url,
|
|
69
64
|
dryRun,
|
|
70
|
-
publisherMintAddress,
|
|
71
65
|
storageParams,
|
|
72
66
|
priorityFeeLamports = Constants.DEFAULT_PRIORITY_FEE,
|
|
73
67
|
}: CreateAppCommandInput) => {
|
|
@@ -78,7 +72,7 @@ export const createAppCommand = async ({
|
|
|
78
72
|
}
|
|
79
73
|
);
|
|
80
74
|
|
|
81
|
-
const { app: appDetails
|
|
75
|
+
const { app: appDetails } =
|
|
82
76
|
await loadPublishDetailsWithChecks();
|
|
83
77
|
|
|
84
78
|
if (!dryRun) {
|
|
@@ -86,7 +80,6 @@ export const createAppCommand = async ({
|
|
|
86
80
|
{
|
|
87
81
|
connection,
|
|
88
82
|
publisher: signer,
|
|
89
|
-
publisherMintAddress: publisherDetails.address ?? publisherMintAddress,
|
|
90
83
|
appDetails,
|
|
91
84
|
storageParams,
|
|
92
85
|
priorityFeeLamports
|
|
@@ -127,7 +127,16 @@ export const createReleaseCommand = async ({
|
|
|
127
127
|
|
|
128
128
|
await writeToPublishDetails(
|
|
129
129
|
{
|
|
130
|
-
release: {
|
|
130
|
+
release: {
|
|
131
|
+
address: releaseAddress,
|
|
132
|
+
android_details: {
|
|
133
|
+
cert_fingerprint: config.release.android_details.cert_fingerprint,
|
|
134
|
+
min_sdk: config.release.android_details.min_sdk,
|
|
135
|
+
version: config.release.android_details.version,
|
|
136
|
+
version_code: config.release.android_details.version_code,
|
|
137
|
+
locales: config.release.android_details.locales
|
|
138
|
+
}
|
|
139
|
+
},
|
|
131
140
|
lastSubmittedVersionOnChain: {
|
|
132
141
|
address: releaseAddress,
|
|
133
142
|
version_code: config.release.android_details.version_code,
|
|
@@ -47,11 +47,10 @@ export const publishRemoveCommand = async ({
|
|
|
47
47
|
const sign = ((buf: Buffer) =>
|
|
48
48
|
nacl.sign(buf, signer.secretKey)) as SignWithPublisherKeypair;
|
|
49
49
|
|
|
50
|
-
const pubAddr = publisherDetails.address;
|
|
51
50
|
const appAddr = appMintAddress ?? appDetails.address;
|
|
52
51
|
const releaseAddr = releaseMintAddress ?? releaseDetails.address;
|
|
53
52
|
|
|
54
|
-
await checkMintedStatus(connection,
|
|
53
|
+
await checkMintedStatus(connection, appAddr, releaseAddr);
|
|
55
54
|
|
|
56
55
|
await publishRemove(
|
|
57
56
|
{ connection, sign },
|
|
@@ -61,7 +61,6 @@ export const publishSubmitCommand = async ({
|
|
|
61
61
|
const sign = ((buf: Buffer) =>
|
|
62
62
|
nacl.sign(buf, signer.secretKey)) as SignWithPublisherKeypair;
|
|
63
63
|
|
|
64
|
-
const pubAddr = publisherDetails.address;
|
|
65
64
|
const appAddr = appMintAddress ?? appDetails.address;
|
|
66
65
|
const releaseAddr = releaseMintAddress ?? releaseDetails.address;
|
|
67
66
|
|
|
@@ -69,7 +68,7 @@ export const publishSubmitCommand = async ({
|
|
|
69
68
|
throw new Error(`You've already submitted this version for review.`);
|
|
70
69
|
}
|
|
71
70
|
|
|
72
|
-
await checkMintedStatus(connection,
|
|
71
|
+
await checkMintedStatus(connection, appAddr, releaseAddr);
|
|
73
72
|
|
|
74
73
|
await publishSubmit(
|
|
75
74
|
{ connection, sign },
|
|
@@ -47,11 +47,10 @@ export const publishSupportCommand = async ({
|
|
|
47
47
|
const sign = ((buf: Buffer) =>
|
|
48
48
|
nacl.sign(buf, signer.secretKey)) as SignWithPublisherKeypair;
|
|
49
49
|
|
|
50
|
-
const pubAddr = publisherDetails.address;
|
|
51
50
|
const appAddr = appMintAddress ?? appDetails.address;
|
|
52
51
|
const releaseAddr = releaseMintAddress ?? releaseDetails.address;
|
|
53
52
|
|
|
54
|
-
await checkMintedStatus(connection,
|
|
53
|
+
await checkMintedStatus(connection, appAddr, releaseAddr);
|
|
55
54
|
|
|
56
55
|
await publishSupport(
|
|
57
56
|
{ connection, sign },
|
|
@@ -69,7 +69,6 @@ export const publishUpdateCommand = async ({
|
|
|
69
69
|
const sign = ((buf: Buffer) =>
|
|
70
70
|
nacl.sign(buf, signer.secretKey)) as SignWithPublisherKeypair;
|
|
71
71
|
|
|
72
|
-
const pubAddr = publisherDetails.address;
|
|
73
72
|
const appAddr = appMintAddress ?? appDetails.address;
|
|
74
73
|
const releaseAddr = releaseMintAddress ?? releaseDetails.address;
|
|
75
74
|
|
|
@@ -77,7 +76,7 @@ export const publishUpdateCommand = async ({
|
|
|
77
76
|
throw new Error(`You've already submitted this version for review.`);
|
|
78
77
|
}
|
|
79
78
|
|
|
80
|
-
await checkMintedStatus(connection,
|
|
79
|
+
await checkMintedStatus(connection, appAddr, releaseAddr);
|
|
81
80
|
|
|
82
81
|
await publishUpdate(
|
|
83
82
|
{ connection, sign },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
2
|
AndroidDetails,
|
|
3
3
|
App,
|
|
4
4
|
LastSubmittedVersionOnChain,
|
|
@@ -48,7 +48,7 @@ const AaptPrefixes = {
|
|
|
48
48
|
type SaveToConfigArgs = {
|
|
49
49
|
publisher?: Pick<Publisher, "address">;
|
|
50
50
|
app?: Pick<App, "address">;
|
|
51
|
-
release?:
|
|
51
|
+
release?: Release;
|
|
52
52
|
lastSubmittedVersionOnChain?: LastSubmittedVersionOnChain;
|
|
53
53
|
lastUpdatedVersionOnStore?: LastUpdatedVersionOnStore;
|
|
54
54
|
};
|
|
@@ -83,25 +83,16 @@ export const loadPublishDetailsWithChecks = async (
|
|
|
83
83
|
throw new Error("Invalid path to APK file.");
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
const developerOverridenLocales = config.release.android_details.locales
|
|
87
|
+
|
|
86
88
|
if (buildToolsDir) {
|
|
87
89
|
config.release.android_details = await getAndroidDetails(
|
|
88
90
|
buildToolsDir,
|
|
89
|
-
apkPath
|
|
91
|
+
apkPath,
|
|
92
|
+
developerOverridenLocales
|
|
90
93
|
);
|
|
91
94
|
}
|
|
92
95
|
|
|
93
|
-
const publisherIcon = config.publisher.media?.find(
|
|
94
|
-
(asset: any) => asset.purpose === "icon"
|
|
95
|
-
)?.uri;
|
|
96
|
-
|
|
97
|
-
if (publisherIcon) {
|
|
98
|
-
const iconPath = path.join(process.cwd(), publisherIcon);
|
|
99
|
-
await checkIconCompatibility(iconPath, "Publisher");
|
|
100
|
-
|
|
101
|
-
const iconBuffer = await fs.promises.readFile(iconPath);
|
|
102
|
-
config.publisher.icon = toMetaplexFile(iconBuffer, publisherIcon);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
96
|
const appIcon = config.app.media?.find(
|
|
106
97
|
(asset: any) => asset.purpose === "icon"
|
|
107
98
|
)?.uri;
|
|
@@ -134,6 +125,8 @@ export const loadPublishDetailsWithChecks = async (
|
|
|
134
125
|
if (banner) {
|
|
135
126
|
const bannerPath = path.join(process.cwd(), banner);
|
|
136
127
|
await checkBannerCompatibility(bannerPath);
|
|
128
|
+
} else {
|
|
129
|
+
throw new Error("Please specify banner image of size 1200x600 in your configuration file");
|
|
137
130
|
}
|
|
138
131
|
|
|
139
132
|
const featureGraphic = config.release.media?.find(
|
|
@@ -322,7 +315,8 @@ const checkVideoDimensions = async (imagePath: string): Promise<boolean> => {
|
|
|
322
315
|
|
|
323
316
|
const getAndroidDetails = async (
|
|
324
317
|
aaptDir: string,
|
|
325
|
-
apkPath: string
|
|
318
|
+
apkPath: string,
|
|
319
|
+
developerOverridenLocales: [string]
|
|
326
320
|
): Promise<AndroidDetails> => {
|
|
327
321
|
try {
|
|
328
322
|
const { stdout } = await runExec(`${aaptDir}/aapt2 dump badging "${apkPath}"`);
|
|
@@ -373,7 +367,7 @@ const getAndroidDetails = async (
|
|
|
373
367
|
);
|
|
374
368
|
}
|
|
375
369
|
|
|
376
|
-
if (permissions.includes("com.solanamobile.seedvault.ACCESS_SEED_VAULT")) {
|
|
370
|
+
if (permissions.includes("com.solanamobile.seedvault.ACCESS_SEED_VAULT") || permissions.includes("com.solanamobile.seedvault.ACCESS_SEED_VAULT_PRIVILEGED")) {
|
|
377
371
|
showMessage(
|
|
378
372
|
"App requests Seed Vault permission",
|
|
379
373
|
"If this is not a wallet application, your app maybe rejected from listing on Solana dApp Store.",
|
|
@@ -381,19 +375,20 @@ const getAndroidDetails = async (
|
|
|
381
375
|
);
|
|
382
376
|
}
|
|
383
377
|
|
|
384
|
-
if (localeArray.length >= 60) {
|
|
378
|
+
if (developerOverridenLocales == null && localeArray.length >= 60 || developerOverridenLocales?.length >= 60) {
|
|
385
379
|
showMessage(
|
|
386
|
-
"
|
|
387
|
-
"
|
|
380
|
+
"Excessive language support detected",
|
|
381
|
+
"The bundle apk claims supports for following locales \n" +
|
|
388
382
|
localeArray +
|
|
389
|
-
"\
|
|
390
|
-
|
|
383
|
+
"\nYou config.yaml claims support for following locales\n" +
|
|
384
|
+
developerOverridenLocales +
|
|
385
|
+
"\nIf this release does not support all these locales the release may be rejected\n." +
|
|
386
|
+
"You can override this list of supported locales in config.yaml" +
|
|
387
|
+
"\nSee details at https://developer.android.com/guide/topics/resources/multilingual-support#design for configuring the supported locales in your apk file",
|
|
391
388
|
"warning"
|
|
392
389
|
);
|
|
393
390
|
}
|
|
394
|
-
|
|
395
|
-
checkAbis(apkPath);
|
|
396
|
-
|
|
391
|
+
|
|
397
392
|
return {
|
|
398
393
|
android_package: appPackage?.[1] ?? "",
|
|
399
394
|
min_sdk: parseInt(minSdk?.[1] ?? "0", 10),
|
|
@@ -401,7 +396,7 @@ const getAndroidDetails = async (
|
|
|
401
396
|
version: versionName?.[1] ?? "0",
|
|
402
397
|
cert_fingerprint: await extractCertFingerprint(aaptDir, apkPath),
|
|
403
398
|
permissions: permissions,
|
|
404
|
-
locales: localeArray
|
|
399
|
+
locales: developerOverridenLocales ?? localeArray
|
|
405
400
|
};
|
|
406
401
|
} catch (e) {
|
|
407
402
|
if (e instanceof TypeError) {
|
|
@@ -412,35 +407,6 @@ const getAndroidDetails = async (
|
|
|
412
407
|
}
|
|
413
408
|
};
|
|
414
409
|
|
|
415
|
-
const checkAbis = async (apkPath: string) => {
|
|
416
|
-
try {
|
|
417
|
-
const { stdout } = await runExec(`zipinfo -s ${apkPath} | grep \.so$`);
|
|
418
|
-
const amV7libs = [...stdout.matchAll(/lib\/armeabi-v7a\/(.*)/g)].flatMap(permission => permission[1]);
|
|
419
|
-
const x86libs = [...stdout.matchAll(/lib\/x86\/(.*)/g)].flatMap(permission => permission[1]);
|
|
420
|
-
const x8664libs = [...stdout.matchAll(/lib\/x86_64\/(.*)/g)].flatMap(permission => permission[1]);
|
|
421
|
-
if (amV7libs.length > 0 || x86libs.length > 0 || x8664libs.length > 0) {
|
|
422
|
-
|
|
423
|
-
const messages = [
|
|
424
|
-
`Solana dApp Store only supports arm64-v8a abi.`,
|
|
425
|
-
`Your apk file contains following unsupported abis`,
|
|
426
|
-
... amV7libs.length > 0 ? [`\narmeabi-v7a:\n` + amV7libs] : [],
|
|
427
|
-
... x86libs.length > 0 ? [`\nx86:\n` + x86libs] : [],
|
|
428
|
-
... x8664libs.length > 0 ? [`\nx86_64:\n` + x8664libs] : [],
|
|
429
|
-
`\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.`,
|
|
430
|
-
`\n\nSee https://developer.android.com/games/optimize/64-bit#build-with-64-bit for how to optimize your app.`,
|
|
431
|
-
].join('\n')
|
|
432
|
-
|
|
433
|
-
showMessage(
|
|
434
|
-
`Unsupported files found in apk`,
|
|
435
|
-
messages,
|
|
436
|
-
`warning`
|
|
437
|
-
)
|
|
438
|
-
}
|
|
439
|
-
} catch (e) {
|
|
440
|
-
// Ignore this error.
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
410
|
export const extractCertFingerprint = async (aaptDir: string, apkPath: string): Promise<string> => {
|
|
445
411
|
const { stdout } = await runExec(`${aaptDir}/apksigner verify --print-certs -v "${apkPath}"`);
|
|
446
412
|
|
|
@@ -454,7 +420,7 @@ export const extractCertFingerprint = async (aaptDir: string, apkPath: string):
|
|
|
454
420
|
}
|
|
455
421
|
}
|
|
456
422
|
|
|
457
|
-
export const writeToPublishDetails = async ({
|
|
423
|
+
export const writeToPublishDetails = async ({ app, release, lastSubmittedVersionOnChain, lastUpdatedVersionOnStore }: SaveToConfigArgs) => {
|
|
458
424
|
const currentConfig = await loadPublishDetailsWithChecks();
|
|
459
425
|
|
|
460
426
|
delete currentConfig.publisher.icon;
|
|
@@ -463,7 +429,6 @@ export const writeToPublishDetails = async ({ publisher, app, release, lastSubmi
|
|
|
463
429
|
const newConfig: PublishDetails = {
|
|
464
430
|
publisher: {
|
|
465
431
|
...currentConfig.publisher,
|
|
466
|
-
address: publisher?.address ?? currentConfig.publisher.address
|
|
467
432
|
},
|
|
468
433
|
app: {
|
|
469
434
|
...currentConfig.app,
|
|
@@ -471,7 +436,14 @@ export const writeToPublishDetails = async ({ publisher, app, release, lastSubmi
|
|
|
471
436
|
},
|
|
472
437
|
release: {
|
|
473
438
|
...currentConfig.release,
|
|
474
|
-
address: release?.address ?? currentConfig.release.address
|
|
439
|
+
address: release?.address ?? currentConfig.release.address,
|
|
440
|
+
android_details: {
|
|
441
|
+
cert_fingerprint: release?.android_details?.cert_fingerprint ?? currentConfig.release.android_details.cert_fingerprint,
|
|
442
|
+
min_sdk: release?.android_details?.min_sdk ?? currentConfig.release.android_details.min_sdk,
|
|
443
|
+
version: release?.android_details?.version ?? currentConfig.release.android_details.version,
|
|
444
|
+
version_code: release?.android_details?.version_code ?? currentConfig.release.android_details.version_code,
|
|
445
|
+
locales: release?.android_details?.locales ?? currentConfig.release.android_details.locales
|
|
446
|
+
}
|
|
475
447
|
},
|
|
476
448
|
solana_mobile_dapp_publisher_portal: currentConfig.solana_mobile_dapp_publisher_portal,
|
|
477
449
|
lastSubmittedVersionOnChain: lastSubmittedVersionOnChain ?? currentConfig.lastSubmittedVersionOnChain,
|
|
@@ -1,63 +1,63 @@
|
|
|
1
1
|
publisher:
|
|
2
|
-
name: <<YOUR_PUBLISHER_NAME>>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
email: <<EMAIL_ADDRESS_TO_CONTACT_PUBLISHER>>
|
|
6
|
-
media:
|
|
7
|
-
- purpose: icon
|
|
8
|
-
uri: <<RELATIVE_PATH_TO_PUBLISHER_ICON>>
|
|
2
|
+
name: <<[REQUIRED] YOUR_PUBLISHER_NAME>>
|
|
3
|
+
website: <<[REQUIRED] URL_OF_PUBLISHER_WEBSITE>>
|
|
4
|
+
email: <<[REQUIRED] EMAIL_ADDRESS_TO_CONTACT_PUBLISHER>>
|
|
9
5
|
app:
|
|
10
|
-
name: <<APP_NAME>>
|
|
6
|
+
name: <<[REQUIRED] APP_NAME>>
|
|
11
7
|
address: ""
|
|
12
|
-
android_package: <<ANDROID_PACKAGE_NAME>>
|
|
8
|
+
android_package: <<[REQUIRED] ANDROID_PACKAGE_NAME>>
|
|
13
9
|
urls:
|
|
14
|
-
license_url: <<
|
|
15
|
-
copyright_url: <<
|
|
16
|
-
privacy_policy_url: <<
|
|
17
|
-
website: <<URL_OF_APP_WEBSITE>>
|
|
10
|
+
license_url: <<[REQUIRED] URL For App's T&C. Don't put placeholder urls.>>
|
|
11
|
+
copyright_url: <<[REQUIRED] URL For App's Copyright. Don't put placeholder urls.>>
|
|
12
|
+
privacy_policy_url: <<[REQUIRED] URL For App's Privacy Policy. Don't put placeholder urls.>>
|
|
13
|
+
website: <<[REQUIRED] URL_OF_APP_WEBSITE>>
|
|
18
14
|
media:
|
|
19
15
|
- purpose: icon
|
|
20
|
-
uri: <<RELATIVE_PATH_TO_APP_ICON>>
|
|
16
|
+
uri: <<[REQUIRED] RELATIVE_PATH_TO_APP_ICON>>
|
|
21
17
|
release:
|
|
22
18
|
address: ""
|
|
23
19
|
media:
|
|
24
20
|
- purpose: icon
|
|
25
|
-
uri: <<RELATIVE_PATH_TO_RELEASE_ICON>>
|
|
21
|
+
uri: <<[REQUIRED] RELATIVE_PATH_TO_RELEASE_ICON>>
|
|
26
22
|
- purpose: banner
|
|
27
|
-
uri: <<RELATIVE_PATH_TO_BANNER>>
|
|
23
|
+
uri: <<[REQUIRED] RELATIVE_PATH_TO_BANNER>>
|
|
28
24
|
- purpose: featureGraphic
|
|
29
|
-
uri: <<RELATIVE_PATH_TO_FEATURE_GRAPHIC>>
|
|
25
|
+
uri: <<[Optional] RELATIVE_PATH_TO_FEATURE_GRAPHIC>>
|
|
30
26
|
- purpose: screenshot
|
|
31
|
-
uri: <<RELATIVE_PATH_TO_SCREENSHOT1>>
|
|
27
|
+
uri: <<[REQUIRED] RELATIVE_PATH_TO_SCREENSHOT1>>
|
|
32
28
|
- purpose: screenshot
|
|
33
|
-
uri: <<RELATIVE_PATH_TO_SCREENSHOT2>>
|
|
29
|
+
uri: <<[REQUIRED] RELATIVE_PATH_TO_SCREENSHOT2>>
|
|
34
30
|
- purpose: screenshot
|
|
35
|
-
uri: <<RELATIVE_PATH_TO_SCREENSHOT3>>
|
|
31
|
+
uri: <<[REQUIRED] RELATIVE_PATH_TO_SCREENSHOT3>>
|
|
36
32
|
- purpose: screenshot
|
|
37
|
-
uri: <<RELATIVE_PATH_TO_SCREENSHOT4>>
|
|
33
|
+
uri: <<[REQUIRED] RELATIVE_PATH_TO_SCREENSHOT4>>
|
|
38
34
|
- purpose: video
|
|
39
|
-
uri: <<RELATIVE_PATH_TO_VIDEO1>>
|
|
35
|
+
uri: <<[Optional] RELATIVE_PATH_TO_VIDEO1>>
|
|
40
36
|
files:
|
|
41
37
|
- purpose: install
|
|
42
|
-
uri: <<RELATIVE_PATH_TO_APK>>
|
|
38
|
+
uri: <<[REQUIRED] RELATIVE_PATH_TO_APK>>
|
|
43
39
|
catalog:
|
|
44
40
|
en-US:
|
|
45
41
|
name: >-
|
|
46
|
-
<<APP_NAME>>
|
|
42
|
+
<<[REQUIRED] APP_NAME>>
|
|
47
43
|
short_description: >-
|
|
48
|
-
<<SHORT_APP_DESCRIPTION>>
|
|
44
|
+
<<[REQUIRED] SHORT_APP_DESCRIPTION>>
|
|
49
45
|
long_description: >-
|
|
50
|
-
<<LONG_APP_DESCRIPTION>>
|
|
46
|
+
<<[REQUIRED] LONG_APP_DESCRIPTION>>
|
|
51
47
|
new_in_version: >-
|
|
52
|
-
<<WHATS_NEW_IN_THIS_VERSION>>
|
|
48
|
+
<<[REQUIRED] WHATS_NEW_IN_THIS_VERSION>>
|
|
53
49
|
saga_features: >-
|
|
54
|
-
<<ANY_FEATURES_ONLY_AVAILBLE_WHEN_RUNNING_ON_SAGA>>
|
|
50
|
+
<<[Optional.] ANY_FEATURES_ONLY_AVAILBLE_WHEN_RUNNING_ON_SAGA>>
|
|
51
|
+
android_details:
|
|
52
|
+
locales:
|
|
53
|
+
- en-US
|
|
54
|
+
- <Add more supported locales>
|
|
55
55
|
solana_mobile_dapp_publisher_portal:
|
|
56
|
-
google_store_package: <<
|
|
56
|
+
google_store_package: <<[Optional] ANDROID_PACKAGE_NAME_OF_GOOGLE_PLAY_STORE_VERSION>>
|
|
57
57
|
testing_instructions: >-
|
|
58
|
-
<<TESTING_INSTRUCTIONS>>
|
|
58
|
+
<<[REQUIRED] TESTING_INSTRUCTIONS. Please provide any test account details if applicable>>
|
|
59
59
|
alpha_testers:
|
|
60
|
-
- address: <<genesis token wallet address>>
|
|
60
|
+
- address: <<Optional. genesis token wallet address>>
|
|
61
61
|
comment: <<Optional. For internal use only>>
|
|
62
|
-
- address: <<genesis token wallet address>>
|
|
62
|
+
- address: <<Optional. genesis token wallet address>>
|
|
63
63
|
comment: <<Optional. For internal use only>>
|
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
2
|
-
try {
|
|
3
|
-
var info = gen[key](arg);
|
|
4
|
-
var value = info.value;
|
|
5
|
-
} catch (error) {
|
|
6
|
-
reject(error);
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
if (info.done) {
|
|
10
|
-
resolve(value);
|
|
11
|
-
} else {
|
|
12
|
-
Promise.resolve(value).then(_next, _throw);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
function _async_to_generator(fn) {
|
|
16
|
-
return function() {
|
|
17
|
-
var self = this, args = arguments;
|
|
18
|
-
return new Promise(function(resolve, reject) {
|
|
19
|
-
var gen = fn.apply(self, args);
|
|
20
|
-
function _next(value) {
|
|
21
|
-
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
22
|
-
}
|
|
23
|
-
function _throw(err) {
|
|
24
|
-
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
25
|
-
}
|
|
26
|
-
_next(undefined);
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function _ts_generator(thisArg, body) {
|
|
31
|
-
var f, y, t, g, _ = {
|
|
32
|
-
label: 0,
|
|
33
|
-
sent: function() {
|
|
34
|
-
if (t[0] & 1) throw t[1];
|
|
35
|
-
return t[1];
|
|
36
|
-
},
|
|
37
|
-
trys: [],
|
|
38
|
-
ops: []
|
|
39
|
-
};
|
|
40
|
-
return g = {
|
|
41
|
-
next: verb(0),
|
|
42
|
-
"throw": verb(1),
|
|
43
|
-
"return": verb(2)
|
|
44
|
-
}, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
45
|
-
return this;
|
|
46
|
-
}), g;
|
|
47
|
-
function verb(n) {
|
|
48
|
-
return function(v) {
|
|
49
|
-
return step([
|
|
50
|
-
n,
|
|
51
|
-
v
|
|
52
|
-
]);
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
function step(op) {
|
|
56
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
57
|
-
while(_)try {
|
|
58
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
59
|
-
if (y = 0, t) op = [
|
|
60
|
-
op[0] & 2,
|
|
61
|
-
t.value
|
|
62
|
-
];
|
|
63
|
-
switch(op[0]){
|
|
64
|
-
case 0:
|
|
65
|
-
case 1:
|
|
66
|
-
t = op;
|
|
67
|
-
break;
|
|
68
|
-
case 4:
|
|
69
|
-
_.label++;
|
|
70
|
-
return {
|
|
71
|
-
value: op[1],
|
|
72
|
-
done: false
|
|
73
|
-
};
|
|
74
|
-
case 5:
|
|
75
|
-
_.label++;
|
|
76
|
-
y = op[1];
|
|
77
|
-
op = [
|
|
78
|
-
0
|
|
79
|
-
];
|
|
80
|
-
continue;
|
|
81
|
-
case 7:
|
|
82
|
-
op = _.ops.pop();
|
|
83
|
-
_.trys.pop();
|
|
84
|
-
continue;
|
|
85
|
-
default:
|
|
86
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
87
|
-
_ = 0;
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
91
|
-
_.label = op[1];
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
if (op[0] === 6 && _.label < t[1]) {
|
|
95
|
-
_.label = t[1];
|
|
96
|
-
t = op;
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
if (t && _.label < t[2]) {
|
|
100
|
-
_.label = t[2];
|
|
101
|
-
_.ops.push(op);
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
if (t[2]) _.ops.pop();
|
|
105
|
-
_.trys.pop();
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
op = body.call(thisArg, _);
|
|
109
|
-
} catch (e) {
|
|
110
|
-
op = [
|
|
111
|
-
6,
|
|
112
|
-
e
|
|
113
|
-
];
|
|
114
|
-
y = 0;
|
|
115
|
-
} finally{
|
|
116
|
-
f = t = 0;
|
|
117
|
-
}
|
|
118
|
-
if (op[0] & 5) throw op[1];
|
|
119
|
-
return {
|
|
120
|
-
value: op[0] ? op[1] : void 0,
|
|
121
|
-
done: true
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
import { createPublisher } from "@solana-mobile/dapp-store-publishing-tools";
|
|
126
|
-
import { Connection, Keypair } from "@solana/web3.js";
|
|
127
|
-
import { Constants, getMetaplexInstance } from "../../CliUtils.js";
|
|
128
|
-
import { loadPublishDetailsWithChecks, writeToPublishDetails } from "../../config/PublishDetails.js";
|
|
129
|
-
import { sendAndConfirmTransaction } from "../utils.js";
|
|
130
|
-
var createPublisherNft = /*#__PURE__*/ function() {
|
|
131
|
-
var _ref = _async_to_generator(function(param) {
|
|
132
|
-
var connection, publisher, publisherDetails, storageParams, priorityFeeLamports, mintAddress, metaplex, txBuilder, response;
|
|
133
|
-
return _ts_generator(this, function(_state) {
|
|
134
|
-
switch(_state.label){
|
|
135
|
-
case 0:
|
|
136
|
-
connection = param.connection, publisher = param.publisher, publisherDetails = param.publisherDetails, storageParams = param.storageParams, priorityFeeLamports = param.priorityFeeLamports;
|
|
137
|
-
console.info("Creating Publisher NFT");
|
|
138
|
-
mintAddress = Keypair.generate();
|
|
139
|
-
metaplex = getMetaplexInstance(connection, publisher, storageParams);
|
|
140
|
-
return [
|
|
141
|
-
4,
|
|
142
|
-
createPublisher({
|
|
143
|
-
mintAddress: mintAddress,
|
|
144
|
-
publisherDetails: publisherDetails,
|
|
145
|
-
priorityFeeLamports: priorityFeeLamports
|
|
146
|
-
}, {
|
|
147
|
-
metaplex: metaplex,
|
|
148
|
-
publisher: publisher
|
|
149
|
-
})
|
|
150
|
-
];
|
|
151
|
-
case 1:
|
|
152
|
-
txBuilder = _state.sent();
|
|
153
|
-
console.info("Publisher NFT data upload complete\nSigning transaction now");
|
|
154
|
-
return [
|
|
155
|
-
4,
|
|
156
|
-
sendAndConfirmTransaction(metaplex, txBuilder)
|
|
157
|
-
];
|
|
158
|
-
case 2:
|
|
159
|
-
response = _state.sent().response;
|
|
160
|
-
return [
|
|
161
|
-
2,
|
|
162
|
-
{
|
|
163
|
-
publisherAddress: mintAddress.publicKey.toBase58(),
|
|
164
|
-
transactionSignature: response.signature
|
|
165
|
-
}
|
|
166
|
-
];
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
return function createPublisherNft(_) {
|
|
171
|
-
return _ref.apply(this, arguments);
|
|
172
|
-
};
|
|
173
|
-
}();
|
|
174
|
-
export var createPublisherCommand = /*#__PURE__*/ function() {
|
|
175
|
-
var _ref = _async_to_generator(function(param) {
|
|
176
|
-
var signer, url, dryRun, storageParams, _param_priorityFeeLamports, priorityFeeLamports, connection, _ref, publisherDetails, _ref1, publisherAddress, transactionSignature;
|
|
177
|
-
return _ts_generator(this, function(_state) {
|
|
178
|
-
switch(_state.label){
|
|
179
|
-
case 0:
|
|
180
|
-
signer = param.signer, url = param.url, dryRun = param.dryRun, storageParams = param.storageParams, _param_priorityFeeLamports = param.priorityFeeLamports, priorityFeeLamports = _param_priorityFeeLamports === void 0 ? Constants.DEFAULT_PRIORITY_FEE : _param_priorityFeeLamports;
|
|
181
|
-
connection = new Connection(url, {
|
|
182
|
-
commitment: "confirmed"
|
|
183
|
-
});
|
|
184
|
-
return [
|
|
185
|
-
4,
|
|
186
|
-
loadPublishDetailsWithChecks()
|
|
187
|
-
];
|
|
188
|
-
case 1:
|
|
189
|
-
_ref = _state.sent(), publisherDetails = _ref.publisher;
|
|
190
|
-
if (!!dryRun) return [
|
|
191
|
-
3,
|
|
192
|
-
4
|
|
193
|
-
];
|
|
194
|
-
return [
|
|
195
|
-
4,
|
|
196
|
-
createPublisherNft({
|
|
197
|
-
connection: connection,
|
|
198
|
-
publisher: signer,
|
|
199
|
-
publisherDetails: publisherDetails,
|
|
200
|
-
storageParams: storageParams,
|
|
201
|
-
priorityFeeLamports: priorityFeeLamports
|
|
202
|
-
})
|
|
203
|
-
];
|
|
204
|
-
case 2:
|
|
205
|
-
_ref1 = _state.sent(), publisherAddress = _ref1.publisherAddress, transactionSignature = _ref1.transactionSignature;
|
|
206
|
-
return [
|
|
207
|
-
4,
|
|
208
|
-
writeToPublishDetails({
|
|
209
|
-
publisher: {
|
|
210
|
-
address: publisherAddress
|
|
211
|
-
}
|
|
212
|
-
})
|
|
213
|
-
];
|
|
214
|
-
case 3:
|
|
215
|
-
_state.sent();
|
|
216
|
-
return [
|
|
217
|
-
2,
|
|
218
|
-
{
|
|
219
|
-
publisherAddress: publisherAddress,
|
|
220
|
-
transactionSignature: transactionSignature
|
|
221
|
-
}
|
|
222
|
-
];
|
|
223
|
-
case 4:
|
|
224
|
-
return [
|
|
225
|
-
2,
|
|
226
|
-
{
|
|
227
|
-
publisherAddress: "",
|
|
228
|
-
transactionSignature: ""
|
|
229
|
-
}
|
|
230
|
-
];
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
return function createPublisherCommand(_) {
|
|
235
|
-
return _ref.apply(this, arguments);
|
|
236
|
-
};
|
|
237
|
-
}();
|