@solana-mobile/dapp-store-cli 0.10.0 → 0.11.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 +16 -26
- 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 +125 -257
- 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 +0 -4
- 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/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 +4 -57
- package/src/prebuild_schema/publishing_source.yaml +0 -4
- package/lib/commands/create/CreateCliPublisher.js +0 -237
- package/src/commands/create/CreateCliPublisher.ts +0 -87
|
@@ -1 +1 @@
|
|
|
1
|
-
{"publisher":{"name":"<<YOUR_PUBLISHER_NAME>>","
|
|
1
|
+
{"publisher":{"name":"<<YOUR_PUBLISHER_NAME>>","website":"<<URL_OF_PUBLISHER_WEBSITE>>","email":"<<EMAIL_ADDRESS_TO_CONTACT_PUBLISHER>>"},"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":"banner","uri":"<<RELATIVE_PATH_TO_BANNER>>"},{"purpose":"featureGraphic","uri":"<<RELATIVE_PATH_TO_FEATURE_GRAPHIC>>"},{"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>>","alpha_testers":[{"address":"<<genesis token wallet address>>","comment":"<<Optional. For internal use only>>"},{"address":"<<genesis token wallet address>>","comment":"<<Optional. For internal use only>>"}]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"object","properties":{"publisher":{"type":"object","properties":{"name":{"type":"string"},"
|
|
1
|
+
{"type":"object","properties":{"publisher":{"type":"object","properties":{"name":{"type":"string"},"website":{"type":"string"},"email":{"type":"string"}}},"app":{"type":"object","properties":{"name":{"type":"string"},"address":{"type":"string"},"android_package":{"type":"string"},"urls":{"type":"object","properties":{"license_url":{"type":"string"},"copyright_url":{"type":"string"},"privacy_policy_url":{"type":"string"},"website":{"type":"string"}}},"media":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string"},"uri":{"type":"string"}}}}}},"release":{"type":"object","properties":{"address":{"type":"string"},"media":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string"},"uri":{"type":"string"}},"required":["purpose","uri"]}},"files":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string"},"uri":{"type":"string"}}}},"catalog":{"type":"object","properties":{"en-US":{"type":"object","properties":{"name":{"type":"string"},"short_description":{"type":"string"},"long_description":{"type":"string"},"new_in_version":{"type":"string"},"saga_features":{"type":"string"}},"required":["short_description"]}}}}},"solana_mobile_dapp_publisher_portal":{"type":"object","properties":{"google_store_package":{"type":"string"},"testing_instructions":{"type":"string"},"alpha_testers":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string"},"comment":{"type":"string"}},"required":["address","comment"]}}}}}}
|
package/lib/index.js
CHANGED
|
@@ -28,7 +28,7 @@ function _async_to_generator(fn) {
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
function _ts_generator(thisArg, body) {
|
|
31
|
-
var f, y, t,
|
|
31
|
+
var f, y, t, _ = {
|
|
32
32
|
label: 0,
|
|
33
33
|
sent: function() {
|
|
34
34
|
if (t[0] & 1) throw t[1];
|
|
@@ -36,12 +36,8 @@ function _ts_generator(thisArg, body) {
|
|
|
36
36
|
},
|
|
37
37
|
trys: [],
|
|
38
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() {
|
|
39
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
40
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
45
41
|
return this;
|
|
46
42
|
}), g;
|
|
47
43
|
function verb(n) {
|
|
@@ -54,7 +50,7 @@ function _ts_generator(thisArg, body) {
|
|
|
54
50
|
}
|
|
55
51
|
function step(op) {
|
|
56
52
|
if (f) throw new TypeError("Generator is already executing.");
|
|
57
|
-
while(_)try {
|
|
53
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
58
54
|
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
55
|
if (y = 0, t) op = [
|
|
60
56
|
op[0] & 2,
|
|
@@ -124,10 +120,7 @@ function _ts_generator(thisArg, body) {
|
|
|
124
120
|
}
|
|
125
121
|
import { mainCli } from "./CliSetup.js";
|
|
126
122
|
function main() {
|
|
127
|
-
return
|
|
128
|
-
}
|
|
129
|
-
function _main() {
|
|
130
|
-
_main = _async_to_generator(function() {
|
|
123
|
+
return _async_to_generator(function() {
|
|
131
124
|
return _ts_generator(this, function(_state) {
|
|
132
125
|
switch(_state.label){
|
|
133
126
|
case 0:
|
|
@@ -142,7 +135,6 @@ function _main() {
|
|
|
142
135
|
];
|
|
143
136
|
}
|
|
144
137
|
});
|
|
145
|
-
});
|
|
146
|
-
return _main.apply(this, arguments);
|
|
138
|
+
})();
|
|
147
139
|
}
|
|
148
140
|
main();
|
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.11.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@aws-sdk/client-s3": "^3.321.1",
|
|
55
55
|
"@metaplex-foundation/js-plugin-aws": "^0.20.0",
|
|
56
|
-
"@solana-mobile/dapp-store-publishing-tools": "workspace:0.
|
|
56
|
+
"@solana-mobile/dapp-store-publishing-tools": "workspace:0.11.0",
|
|
57
57
|
"@solana/web3.js": "1.92.1",
|
|
58
58
|
"@types/semver": "^7.3.13",
|
|
59
59
|
"ajv": "^8.11.0",
|
|
@@ -75,7 +75,7 @@ function _object_spread(target) {
|
|
|
75
75
|
return target;
|
|
76
76
|
}
|
|
77
77
|
function _ts_generator(thisArg, body) {
|
|
78
|
-
var f, y, t,
|
|
78
|
+
var f, y, t, _ = {
|
|
79
79
|
label: 0,
|
|
80
80
|
sent: function() {
|
|
81
81
|
if (t[0] & 1) throw t[1];
|
|
@@ -83,12 +83,8 @@ function _ts_generator(thisArg, body) {
|
|
|
83
83
|
},
|
|
84
84
|
trys: [],
|
|
85
85
|
ops: []
|
|
86
|
-
};
|
|
87
|
-
return g = {
|
|
88
|
-
next: verb(0),
|
|
89
|
-
"throw": verb(1),
|
|
90
|
-
"return": verb(2)
|
|
91
|
-
}, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
86
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
87
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
92
88
|
return this;
|
|
93
89
|
}), g;
|
|
94
90
|
function verb(n) {
|
|
@@ -101,7 +97,7 @@ function _ts_generator(thisArg, body) {
|
|
|
101
97
|
}
|
|
102
98
|
function step(op) {
|
|
103
99
|
if (f) throw new TypeError("Generator is already executing.");
|
|
104
|
-
while(_)try {
|
|
100
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
105
101
|
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;
|
|
106
102
|
if (y = 0, t) op = [
|
|
107
103
|
op[0] & 2,
|
|
@@ -192,15 +188,14 @@ export var CachedStorageDriver = /*#__PURE__*/ function() {
|
|
|
192
188
|
{
|
|
193
189
|
key: "getUploadPrice",
|
|
194
190
|
value: function getUploadPrice(bytes) {
|
|
195
|
-
var _this = this;
|
|
196
191
|
return _async_to_generator(function() {
|
|
197
192
|
return _ts_generator(this, function(_state) {
|
|
198
193
|
return [
|
|
199
194
|
2,
|
|
200
|
-
|
|
195
|
+
this.storageDriver.getUploadPrice(bytes)
|
|
201
196
|
];
|
|
202
197
|
});
|
|
203
|
-
})();
|
|
198
|
+
}).call(this);
|
|
204
199
|
}
|
|
205
200
|
},
|
|
206
201
|
{
|
|
@@ -228,7 +223,6 @@ export var CachedStorageDriver = /*#__PURE__*/ function() {
|
|
|
228
223
|
{
|
|
229
224
|
key: "upload",
|
|
230
225
|
value: function upload(file) {
|
|
231
|
-
var _this = this;
|
|
232
226
|
return _async_to_generator(function() {
|
|
233
227
|
var hash, uploadedAsset, uri;
|
|
234
228
|
return _ts_generator(this, function(_state) {
|
|
@@ -240,7 +234,7 @@ export var CachedStorageDriver = /*#__PURE__*/ function() {
|
|
|
240
234
|
];
|
|
241
235
|
return [
|
|
242
236
|
4,
|
|
243
|
-
|
|
237
|
+
this.storageDriver.upload(file)
|
|
244
238
|
];
|
|
245
239
|
case 1:
|
|
246
240
|
return [
|
|
@@ -249,7 +243,7 @@ export var CachedStorageDriver = /*#__PURE__*/ function() {
|
|
|
249
243
|
];
|
|
250
244
|
case 2:
|
|
251
245
|
hash = createHash("sha256").update(file.buffer).digest("base64");
|
|
252
|
-
uploadedAsset =
|
|
246
|
+
uploadedAsset = this.uploadedAsset(file.fileName, {
|
|
253
247
|
sha256: hash
|
|
254
248
|
});
|
|
255
249
|
if (uploadedAsset) {
|
|
@@ -262,20 +256,20 @@ export var CachedStorageDriver = /*#__PURE__*/ function() {
|
|
|
262
256
|
console.log("Uploading ".concat(file.fileName));
|
|
263
257
|
return [
|
|
264
258
|
4,
|
|
265
|
-
|
|
259
|
+
this.storageDriver.upload(file)
|
|
266
260
|
];
|
|
267
261
|
case 3:
|
|
268
262
|
uri = _state.sent();
|
|
269
|
-
|
|
263
|
+
this.assetManifest.assets[file.fileName] = {
|
|
270
264
|
path: file.fileName,
|
|
271
265
|
sha256: hash,
|
|
272
266
|
uri: uri
|
|
273
267
|
};
|
|
274
268
|
return [
|
|
275
269
|
4,
|
|
276
|
-
fs.promises.writeFile("".concat(process.cwd(), "/").concat(
|
|
270
|
+
fs.promises.writeFile("".concat(process.cwd(), "/").concat(this.assetManifestPath), // Something is really weird, I can't seem to stringify `this.assetManifest` straight-up. Here be dragons
|
|
277
271
|
JSON.stringify({
|
|
278
|
-
assets: _object_spread({},
|
|
272
|
+
assets: _object_spread({}, this.assetManifest.assets)
|
|
279
273
|
}, null, 2), "utf-8")
|
|
280
274
|
];
|
|
281
275
|
case 4:
|
|
@@ -287,7 +281,7 @@ export var CachedStorageDriver = /*#__PURE__*/ function() {
|
|
|
287
281
|
];
|
|
288
282
|
}
|
|
289
283
|
});
|
|
290
|
-
})();
|
|
284
|
+
}).call(this);
|
|
291
285
|
}
|
|
292
286
|
}
|
|
293
287
|
]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana-mobile/dapp-store-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@aws-sdk/client-s3": "^3.321.1",
|
|
48
48
|
"@metaplex-foundation/js-plugin-aws": "^0.20.0",
|
|
49
|
-
"@solana-mobile/dapp-store-publishing-tools": "0.
|
|
49
|
+
"@solana-mobile/dapp-store-publishing-tools": "0.11.0",
|
|
50
50
|
"@solana/web3.js": "1.92.1",
|
|
51
51
|
"@types/semver": "^7.3.13",
|
|
52
52
|
"ajv": "^8.11.0",
|
package/src/CliSetup.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { validateCommand } from "./commands/index.js";
|
|
3
|
-
import { createAppCommand,
|
|
3
|
+
import { createAppCommand, createReleaseCommand } from "./commands/create/index.js";
|
|
4
4
|
import {
|
|
5
5
|
publishRemoveCommand,
|
|
6
6
|
publishSubmitCommand,
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
showMessage,
|
|
19
19
|
showNetworkWarningIfApplicable
|
|
20
20
|
} from "./CliUtils.js";
|
|
21
|
-
import { LAMPORTS_PER_SOL } from "@solana/web3.js"
|
|
22
21
|
import * as dotenv from "dotenv";
|
|
23
22
|
import { initScaffold } from "./commands/scaffolding/index.js";
|
|
24
23
|
import { loadPublishDetails, loadPublishDetailsWithChecks } from "./config/PublishDetails.js";
|
|
@@ -51,11 +50,8 @@ function resolveBuildToolsPath(buildToolsPath: string | undefined) {
|
|
|
51
50
|
*/
|
|
52
51
|
function latestReleaseMessage() {
|
|
53
52
|
const messages = [
|
|
54
|
-
`-
|
|
55
|
-
`-
|
|
56
|
-
`- 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"`,
|
|
57
|
-
`- At least 4 screenshots are now required to update or release a new app`,
|
|
58
|
-
`- App icons should be exactly 512x512.`
|
|
53
|
+
`- Banner Graphic image of size 1200x600px is now manadatory for publishing updates.`,
|
|
54
|
+
`- Feature Graphic image of size 1200x1200px is required to be featured in Editor's choice carousel. (optional)`,
|
|
59
55
|
].join('\n\n')
|
|
60
56
|
showMessage(
|
|
61
57
|
`Publishing Tools Version ${ Constants.CLI_VERSION }`,
|
|
@@ -93,41 +89,7 @@ export const initCliCmd = mainCli
|
|
|
93
89
|
|
|
94
90
|
export const createCliCmd = mainCli
|
|
95
91
|
.command("create")
|
|
96
|
-
.description("Create a `
|
|
97
|
-
|
|
98
|
-
export const createPublisherCliCmd = createCliCmd
|
|
99
|
-
.command("publisher")
|
|
100
|
-
.description("Create a publisher")
|
|
101
|
-
.requiredOption(
|
|
102
|
-
"-k, --keypair <path-to-keypair-file>",
|
|
103
|
-
"Path to keypair file"
|
|
104
|
-
)
|
|
105
|
-
.option("-u, --url <url>", "RPC URL", Constants.DEFAULT_RPC_DEVNET)
|
|
106
|
-
.option("-d, --dry-run", "Flag for dry run. Doesn't mint an NFT")
|
|
107
|
-
.option("-s, --storage-config <storage-config>", "Provide alternative storage configuration details")
|
|
108
|
-
.option("-p, --priority-fee-lamports <priority-fee-lamports>", "Priority Fee lamports")
|
|
109
|
-
.action(async ({ keypair, url, dryRun, storageConfig, priorityFeeLamports }) => {
|
|
110
|
-
await tryWithErrorMessage(async () => {
|
|
111
|
-
showNetworkWarningIfApplicable(url)
|
|
112
|
-
latestReleaseMessage();
|
|
113
|
-
await checkForSelfUpdate();
|
|
114
|
-
|
|
115
|
-
const signer = parseKeypair(keypair);
|
|
116
|
-
if (signer) {
|
|
117
|
-
const result: { publisherAddress: string, transactionSignature: string } = await createPublisherCommand({ signer, url, dryRun, storageParams: storageConfig, priorityFeeLamports });
|
|
118
|
-
|
|
119
|
-
if (dryRun) {
|
|
120
|
-
dryRunSuccessMessage()
|
|
121
|
-
} else {
|
|
122
|
-
const displayUrl = `https://explorer.solana.com/address/${result.publisherAddress}${generateNetworkSuffix(url)}`;
|
|
123
|
-
const transactionUrl = `https://explorer.solana.com/tx/${result.transactionSignature}${generateNetworkSuffix(url)}`;
|
|
124
|
-
const resultText = `Publisher NFT successfully minted successfully:\n${displayUrl}\n${transactionUrl}`;
|
|
125
|
-
|
|
126
|
-
showMessage("Success", resultText);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
});
|
|
92
|
+
.description("Create a `app`, or `release`")
|
|
131
93
|
|
|
132
94
|
export const createAppCliCmd = createCliCmd
|
|
133
95
|
.command("app")
|
|
@@ -136,30 +98,19 @@ export const createAppCliCmd = createCliCmd
|
|
|
136
98
|
"-k, --keypair <path-to-keypair-file>",
|
|
137
99
|
"Path to keypair file"
|
|
138
100
|
)
|
|
139
|
-
.option(
|
|
140
|
-
"-p, --publisher-mint-address <publisher-mint-address>",
|
|
141
|
-
"The mint address of the publisher NFT"
|
|
142
|
-
)
|
|
143
101
|
.option("-u, --url <url>", "RPC URL", Constants.DEFAULT_RPC_DEVNET)
|
|
144
102
|
.option("-d, --dry-run", "Flag for dry run. Doesn't mint an NFT")
|
|
145
103
|
.option("-s, --storage-config <storage-config>", "Provide alternative storage configuration details")
|
|
146
104
|
.option("-p, --priority-fee-lamports <priority-fee-lamports>", "Priority Fee lamports")
|
|
147
|
-
.action(async ({
|
|
105
|
+
.action(async ({keypair, url, dryRun, storageConfig, priorityFeeLamports }) => {
|
|
148
106
|
await tryWithErrorMessage(async () => {
|
|
149
107
|
showNetworkWarningIfApplicable(url)
|
|
150
108
|
latestReleaseMessage();
|
|
151
109
|
await checkForSelfUpdate();
|
|
152
110
|
|
|
153
|
-
const config = await loadPublishDetailsWithChecks();
|
|
154
|
-
|
|
155
|
-
if (!hasAddressInConfig(config.publisher) && !publisherMintAddress) {
|
|
156
|
-
throw new Error("Either specify a publisher mint address in the config file or specify as a CLI argument to this command.");
|
|
157
|
-
}
|
|
158
|
-
|
|
159
111
|
const signer = parseKeypair(keypair);
|
|
160
112
|
if (signer) {
|
|
161
113
|
const result = await createAppCommand({
|
|
162
|
-
publisherMintAddress: publisherMintAddress,
|
|
163
114
|
signer,
|
|
164
115
|
url,
|
|
165
116
|
dryRun,
|
package/src/CliUtils.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { awsStorage } from "@metaplex-foundation/js-plugin-aws";
|
|
|
19
19
|
import { S3StorageManager } from "./config/index.js";
|
|
20
20
|
|
|
21
21
|
export class Constants {
|
|
22
|
-
static CLI_VERSION = "0.
|
|
22
|
+
static CLI_VERSION = "0.11.0";
|
|
23
23
|
static CONFIG_FILE_NAME = "config.yaml";
|
|
24
24
|
static DEFAULT_RPC_DEVNET = "https://api.devnet.solana.com";
|
|
25
25
|
static DEFAULT_PRIORITY_FEE = 500000;
|
|
@@ -50,28 +50,22 @@ export const checkForSelfUpdate = async () => {
|
|
|
50
50
|
|
|
51
51
|
export const checkMintedStatus = async (
|
|
52
52
|
conn: Connection,
|
|
53
|
-
pubAddr: string,
|
|
54
53
|
appAddr: string,
|
|
55
54
|
releaseAddr: string
|
|
56
55
|
) => {
|
|
57
56
|
for (let i = 0; i < 5; i++) {
|
|
58
57
|
const results = await conn.getMultipleAccountsInfo([
|
|
59
|
-
new PublicKey(pubAddr),
|
|
60
58
|
new PublicKey(appAddr),
|
|
61
59
|
new PublicKey(releaseAddr),
|
|
62
60
|
]);
|
|
63
61
|
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
const isReleaseMinted = results[2] != undefined && results[2]?.lamports > 0
|
|
62
|
+
const isAppMinted = results[0] != undefined && results[0]?.lamports > 0
|
|
63
|
+
const isReleaseMinted = results[1] != undefined && results[1]?.lamports > 0
|
|
67
64
|
|
|
68
|
-
if (
|
|
65
|
+
if (isAppMinted && isReleaseMinted) {
|
|
69
66
|
return
|
|
70
67
|
} else {
|
|
71
68
|
let errorMessage = ``
|
|
72
|
-
if (!isPublisherMinted) {
|
|
73
|
-
errorMessage = errorMessage + `Publisher NFT fetch at address ${pubAddr} failed.\n`
|
|
74
|
-
}
|
|
75
69
|
if (!isAppMinted) {
|
|
76
70
|
errorMessage = errorMessage + `App NFT fetch at address ${appAddr} failed.\n`
|
|
77
71
|
}
|
|
@@ -80,7 +74,7 @@ export const checkMintedStatus = async (
|
|
|
80
74
|
}
|
|
81
75
|
if (i == 4) {
|
|
82
76
|
throw new Error(
|
|
83
|
-
`Expected
|
|
77
|
+
`Expected App :: ${appAddr} and Release :: ${releaseAddr} to be minted before submission.\n
|
|
84
78
|
but ${errorMessage}\n
|
|
85
79
|
Please ensure you have minted all of your NFTs before submitting to the Solana Mobile dApp publisher portal.`
|
|
86
80
|
);
|
|
@@ -2,7 +2,6 @@ import { beforeEach, expect } from "@jest/globals";
|
|
|
2
2
|
import {
|
|
3
3
|
createAppCliCmd,
|
|
4
4
|
createCliCmd,
|
|
5
|
-
createPublisherCliCmd,
|
|
6
5
|
createReleaseCliCmd,
|
|
7
6
|
initCliCmd,
|
|
8
7
|
mainCli
|
|
@@ -71,25 +70,6 @@ describe("Cli Setup & Execution", () => {
|
|
|
71
70
|
expect(errorOutput).toEqual(createHelp)
|
|
72
71
|
});
|
|
73
72
|
|
|
74
|
-
test("Calling create publisher command with no arguments warns about required argument", () => {
|
|
75
|
-
createPublisherCliCmd.exitOverride()
|
|
76
|
-
|
|
77
|
-
expect(() => {
|
|
78
|
-
createPublisherCliCmd.parse(["dapp-store", "create", "publisher"]);
|
|
79
|
-
}
|
|
80
|
-
).toThrow(keyPairArgHelp);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
test("Calling create publisher command with help flag shows contextual help", () => {
|
|
84
|
-
createPublisherCliCmd.exitOverride()
|
|
85
|
-
|
|
86
|
-
expect(() => {
|
|
87
|
-
createPublisherCliCmd.parse(["dapp-store", "create", "publisher", "-h"]);
|
|
88
|
-
}).toThrow(outputHelpReference)
|
|
89
|
-
|
|
90
|
-
expect(otherOutput).toEqual(createPublisherHelp)
|
|
91
|
-
});
|
|
92
|
-
|
|
93
73
|
test("Calling create app command with no arguments warns about required argument", () => {
|
|
94
74
|
createAppCliCmd.exitOverride()
|
|
95
75
|
|
|
@@ -140,7 +120,7 @@ Options:
|
|
|
140
120
|
|
|
141
121
|
Commands:
|
|
142
122
|
init First-time initialization of tooling configuration
|
|
143
|
-
create Create a \`
|
|
123
|
+
create Create a \`app\`, or \`release\`
|
|
144
124
|
validate [options] Validates details prior to publishing
|
|
145
125
|
publish Submit a publishing request (\`submit\`, \`update\`, \`remove\`, or \`support\`) to the Solana Mobile dApp publisher portal
|
|
146
126
|
help [command] display help for command
|
|
@@ -158,21 +138,20 @@ Options:
|
|
|
158
138
|
|
|
159
139
|
const createHelp = `Usage: dapp-store create [options] [command]
|
|
160
140
|
|
|
161
|
-
Create a \`
|
|
141
|
+
Create a \`app\`, or \`release\`
|
|
162
142
|
|
|
163
143
|
Options:
|
|
164
|
-
-h, --help
|
|
144
|
+
-h, --help display help for command
|
|
165
145
|
|
|
166
146
|
Commands:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
help [command] display help for command
|
|
147
|
+
app [options] Create a app
|
|
148
|
+
release [options] Create a release
|
|
149
|
+
help [command] display help for command
|
|
171
150
|
`;
|
|
172
151
|
|
|
173
|
-
const
|
|
152
|
+
const createAppHelp = `Usage: dapp-store create app [options]
|
|
174
153
|
|
|
175
|
-
Create a
|
|
154
|
+
Create a app
|
|
176
155
|
|
|
177
156
|
Options:
|
|
178
157
|
-k, --keypair <path-to-keypair-file> Path to keypair file
|
|
@@ -183,20 +162,6 @@ Options:
|
|
|
183
162
|
-h, --help display help for command
|
|
184
163
|
`;
|
|
185
164
|
|
|
186
|
-
const createAppHelp = `Usage: dapp-store create app [options]
|
|
187
|
-
|
|
188
|
-
Create a app
|
|
189
|
-
|
|
190
|
-
Options:
|
|
191
|
-
-k, --keypair <path-to-keypair-file> Path to keypair file
|
|
192
|
-
-p, --publisher-mint-address <publisher-mint-address> The mint address of the publisher NFT
|
|
193
|
-
-u, --url <url> RPC URL (default: "https://api.devnet.solana.com")
|
|
194
|
-
-d, --dry-run Flag for dry run. Doesn't mint an NFT
|
|
195
|
-
-s, --storage-config <storage-config> Provide alternative storage configuration details
|
|
196
|
-
-p, --priority-fee-lamports <priority-fee-lamports> Priority Fee lamports
|
|
197
|
-
-h, --help display help for command
|
|
198
|
-
`;
|
|
199
|
-
|
|
200
165
|
const createReleaseHelp = `Usage: dapp-store create release [options]
|
|
201
166
|
|
|
202
167
|
Create a release
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createAppJson,
|
|
3
|
-
createPublisherJson,
|
|
4
3
|
createReleaseJson,
|
|
5
4
|
validateApp,
|
|
6
|
-
validatePublisher,
|
|
7
5
|
validateRelease,
|
|
8
6
|
metaplexFileReplacer,
|
|
9
7
|
} from "@solana-mobile/dapp-store-publishing-tools";
|
|
@@ -28,24 +26,6 @@ export const validateCommand = async ({
|
|
|
28
26
|
|
|
29
27
|
debug({ publisherDetails, appDetails, releaseDetails });
|
|
30
28
|
|
|
31
|
-
const publisherJson = createPublisherJson(publisherDetails);
|
|
32
|
-
if (typeof publisherJson.image !== "string") {
|
|
33
|
-
publisherJson.image = (publisherJson.image as MetaplexFile)?.fileName;
|
|
34
|
-
}
|
|
35
|
-
debug("publisherJson=", JSON.stringify({ publisherJson }, metaplexFileReplacer, 2));
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
validatePublisher(publisherJson);
|
|
39
|
-
} catch (e) {
|
|
40
|
-
const errorMsg = (e as Error | null)?.message ?? "";
|
|
41
|
-
showMessage(
|
|
42
|
-
"Publisher JSON invalid",
|
|
43
|
-
errorMsg,
|
|
44
|
-
"error"
|
|
45
|
-
)
|
|
46
|
-
return
|
|
47
|
-
}
|
|
48
|
-
|
|
49
29
|
const appJson = createAppJson(appDetails, signer.publicKey);
|
|
50
30
|
if (typeof appJson.image !== "string") {
|
|
51
31
|
appJson.image = (appJson.image as MetaplexFile)?.fileName;
|
|
@@ -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
|
|
@@ -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 },
|