@solana-mobile/dapp-store-cli 0.1.1-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.
Files changed (86) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +142 -0
  3. package/bin/dapp-store.js +3 -0
  4. package/lib/esm/commands/create/app.js +37 -0
  5. package/lib/esm/commands/create/app.js.map +1 -0
  6. package/lib/esm/commands/create/index.js +44 -0
  7. package/lib/esm/commands/create/index.js.map +1 -0
  8. package/lib/esm/commands/create/publisher.js +33 -0
  9. package/lib/esm/commands/create/publisher.js.map +1 -0
  10. package/lib/esm/commands/create/release.js +48 -0
  11. package/lib/esm/commands/create/release.js.map +1 -0
  12. package/lib/esm/commands/index.js +4 -0
  13. package/lib/esm/commands/index.js.map +1 -0
  14. package/lib/esm/commands/publish/index.js +25 -0
  15. package/lib/esm/commands/publish/index.js.map +1 -0
  16. package/lib/esm/commands/publish/remove.js +20 -0
  17. package/lib/esm/commands/publish/remove.js.map +1 -0
  18. package/lib/esm/commands/publish/submit.js +25 -0
  19. package/lib/esm/commands/publish/submit.js.map +1 -0
  20. package/lib/esm/commands/publish/support.js +20 -0
  21. package/lib/esm/commands/publish/support.js.map +1 -0
  22. package/lib/esm/commands/publish/update.js +26 -0
  23. package/lib/esm/commands/publish/update.js.map +1 -0
  24. package/lib/esm/commands/validate.js +40 -0
  25. package/lib/esm/commands/validate.js.map +1 -0
  26. package/lib/esm/config/index.js +19 -0
  27. package/lib/esm/config/index.js.map +1 -0
  28. package/lib/esm/config/schema.json +228 -0
  29. package/lib/esm/index.js +259 -0
  30. package/lib/esm/index.js.map +1 -0
  31. package/lib/esm/upload/CachedStorageDriver.js +64 -0
  32. package/lib/esm/upload/CachedStorageDriver.js.map +1 -0
  33. package/lib/esm/upload/index.js +2 -0
  34. package/lib/esm/upload/index.js.map +1 -0
  35. package/lib/esm/utils.js +171 -0
  36. package/lib/esm/utils.js.map +1 -0
  37. package/lib/types/commands/create/app.d.ts +12 -0
  38. package/lib/types/commands/create/app.d.ts.map +1 -0
  39. package/lib/types/commands/create/index.d.ts +4 -0
  40. package/lib/types/commands/create/index.d.ts.map +1 -0
  41. package/lib/types/commands/create/publisher.d.ts +9 -0
  42. package/lib/types/commands/create/publisher.d.ts.map +1 -0
  43. package/lib/types/commands/create/release.d.ts +14 -0
  44. package/lib/types/commands/create/release.d.ts.map +1 -0
  45. package/lib/types/commands/index.d.ts +4 -0
  46. package/lib/types/commands/index.d.ts.map +1 -0
  47. package/lib/types/commands/publish/index.d.ts +5 -0
  48. package/lib/types/commands/publish/index.d.ts.map +1 -0
  49. package/lib/types/commands/publish/remove.d.ts +12 -0
  50. package/lib/types/commands/publish/remove.d.ts.map +1 -0
  51. package/lib/types/commands/publish/submit.d.ts +12 -0
  52. package/lib/types/commands/publish/submit.d.ts.map +1 -0
  53. package/lib/types/commands/publish/support.d.ts +12 -0
  54. package/lib/types/commands/publish/support.d.ts.map +1 -0
  55. package/lib/types/commands/publish/update.d.ts +13 -0
  56. package/lib/types/commands/publish/update.d.ts.map +1 -0
  57. package/lib/types/commands/validate.d.ts +6 -0
  58. package/lib/types/commands/validate.d.ts.map +1 -0
  59. package/lib/types/config/index.d.ts +10 -0
  60. package/lib/types/config/index.d.ts.map +1 -0
  61. package/lib/types/index.d.ts +2 -0
  62. package/lib/types/index.d.ts.map +1 -0
  63. package/lib/types/upload/CachedStorageDriver.d.ts +30 -0
  64. package/lib/types/upload/CachedStorageDriver.d.ts.map +1 -0
  65. package/lib/types/upload/index.d.ts +2 -0
  66. package/lib/types/upload/index.d.ts.map +1 -0
  67. package/lib/types/utils.d.ts +21 -0
  68. package/lib/types/utils.d.ts.map +1 -0
  69. package/package.json +49 -0
  70. package/src/commands/create/app.ts +88 -0
  71. package/src/commands/create/index.ts +48 -0
  72. package/src/commands/create/publisher.ts +78 -0
  73. package/src/commands/create/release.ts +107 -0
  74. package/src/commands/index.ts +3 -0
  75. package/src/commands/publish/index.ts +29 -0
  76. package/src/commands/publish/remove.ts +46 -0
  77. package/src/commands/publish/submit.ts +55 -0
  78. package/src/commands/publish/support.ts +46 -0
  79. package/src/commands/publish/update.ts +58 -0
  80. package/src/commands/validate.ts +67 -0
  81. package/src/config/index.ts +40 -0
  82. package/src/config/schema.json +228 -0
  83. package/src/index.ts +435 -0
  84. package/src/upload/CachedStorageDriver.ts +104 -0
  85. package/src/upload/index.ts +1 -0
  86. package/src/utils.ts +275 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support.js","sourceRoot":"","sources":["../../../../src/commands/publish/support.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAW,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,IAAI,MAAM,WAAW,CAAC;AAW7B,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EAAE,EAC1C,kBAAkB,EAClB,MAAM,EACN,GAAG,EACH,MAAM,GAAG,KAAK,EACd,qBAAqB,GAAG,KAAK,EAC7B,cAAc,GACa,EAAE,EAAE;IAC/B,IAAI,CAAC,qBAAqB,EAAE;QAC1B,OAAO,CAAC,KAAK,CACX,qGAAqG,CACtG,CAAC;QACF,OAAO;KACR;IAED,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,MAAM,aAAa,EAAE,CAAC;IAC9D,MAAM,IAAI,GAAG,CAAC,CAAC,GAAW,EAAE,EAAE,CAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,CAA6B,CAAC;IAEhE,MAAM,cAAc,CAClB,EAAE,UAAU,EAAE,IAAI,EAAE,EACpB;QACE,kBAAkB;QAClB,gBAAgB;QAChB,qBAAqB;QACrB,cAAc;KACf,EACD,MAAM,CACP,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { Connection } from "@solana/web3.js";
2
+ import { publishUpdate } from "@solana-mobile/dapp-store-publishing-tools";
3
+ import { getConfigFile } from "../../utils.js";
4
+ import nacl from "tweetnacl";
5
+ export const publishUpdateCommand = async ({ releaseMintAddress, signer, url, dryRun = false, compliesWithSolanaDappStorePolicies = false, requestorIsAuthorized = false, critical = false, }) => {
6
+ if (!compliesWithSolanaDappStorePolicies) {
7
+ console.error("ERROR: Cannot submit a request for which the requestor does not attest that it complies with Solana dApp Store policies");
8
+ return;
9
+ }
10
+ else if (!requestorIsAuthorized) {
11
+ console.error("ERROR: Cannot submit a request for which the requestor does not attest they are authorized to do so");
12
+ return;
13
+ }
14
+ const connection = new Connection(url);
15
+ const { publisher: publisherDetails, solana_mobile_dapp_publisher_portal: solanaMobileDappPublisherPortalDetails, } = await getConfigFile();
16
+ const sign = ((buf) => nacl.sign(buf, signer.secretKey));
17
+ await publishUpdate({ connection, sign }, {
18
+ releaseMintAddress,
19
+ publisherDetails,
20
+ solanaMobileDappPublisherPortalDetails,
21
+ compliesWithSolanaDappStorePolicies,
22
+ requestorIsAuthorized,
23
+ criticalUpdate: critical,
24
+ }, dryRun);
25
+ };
26
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../../src/commands/publish/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAW,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,IAAI,MAAM,WAAW,CAAC;AAY7B,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,EACzC,kBAAkB,EAClB,MAAM,EACN,GAAG,EACH,MAAM,GAAG,KAAK,EACd,mCAAmC,GAAG,KAAK,EAC3C,qBAAqB,GAAG,KAAK,EAC7B,QAAQ,GAAG,KAAK,GACU,EAAE,EAAE;IAC9B,IAAI,CAAC,mCAAmC,EAAE;QACxC,OAAO,CAAC,KAAK,CACX,yHAAyH,CAC1H,CAAC;QACF,OAAO;KACR;SAAM,IAAI,CAAC,qBAAqB,EAAE;QACjC,OAAO,CAAC,KAAK,CACX,qGAAqG,CACtG,CAAC;QACF,OAAO;KACR;IAED,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,EACJ,SAAS,EAAE,gBAAgB,EAC3B,mCAAmC,EAAE,sCAAsC,GAC5E,GAAG,MAAM,aAAa,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,GAAW,EAAE,EAAE,CAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,CAA6B,CAAC;IAEhE,MAAM,aAAa,CACjB,EAAE,UAAU,EAAE,IAAI,EAAE,EACpB;QACE,kBAAkB;QAClB,gBAAgB;QAChB,sCAAsC;QACtC,mCAAmC;QACnC,qBAAqB;QACrB,cAAc,EAAE,QAAQ;KACzB,EACD,MAAM,CACP,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { createAppJson, createPublisherJson, createReleaseJson, validateApp, validatePublisher, validateRelease, } from "@solana-mobile/dapp-store-publishing-tools";
2
+ import { debug, getConfigFile } from "../utils.js";
3
+ export const validateCommand = async ({ signer, buildToolsPath, }) => {
4
+ const { publisher: publisherDetails, app: appDetails, release: releaseDetails, } = await getConfigFile(buildToolsPath);
5
+ debug({ publisherDetails, appDetails, releaseDetails });
6
+ const publisherJson = createPublisherJson(publisherDetails);
7
+ if (typeof publisherJson.image !== "string") {
8
+ publisherJson.image = publisherJson.image?.fileName;
9
+ }
10
+ debug(JSON.stringify({ publisherJson }, null, 2));
11
+ try {
12
+ validatePublisher(publisherJson);
13
+ console.info(`Publisher JSON valid!`);
14
+ }
15
+ catch (e) {
16
+ console.error(e);
17
+ }
18
+ const appJson = createAppJson(appDetails, signer.publicKey);
19
+ if (typeof appJson.image !== "string") {
20
+ appJson.image = appJson.image?.fileName;
21
+ }
22
+ debug(JSON.stringify({ appJson }, null, 2));
23
+ try {
24
+ validateApp(appJson);
25
+ console.info(`App JSON valid!`);
26
+ }
27
+ catch (e) {
28
+ console.error(e);
29
+ }
30
+ const releaseJson = await createReleaseJson({ releaseDetails, appDetails, publisherDetails }, signer.publicKey);
31
+ debug(JSON.stringify({ releaseJson }, null, 2));
32
+ try {
33
+ validateRelease(releaseJson);
34
+ console.info(`Release JSON valid!`);
35
+ }
36
+ catch (e) {
37
+ console.error(e);
38
+ }
39
+ };
40
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,eAAe,GAChB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKnD,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,EACpC,MAAM,EACN,cAAc,GAIf,EAAE,EAAE;IACH,MAAM,EACJ,SAAS,EAAE,gBAAgB,EAC3B,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,cAAc,GACxB,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,CAAC;IAExC,KAAK,CAAC,EAAE,gBAAgB,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC;IAExD,MAAM,aAAa,GAAG,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;IAC5D,IAAI,OAAO,aAAa,CAAC,KAAK,KAAK,QAAQ,EAAE;QAC3C,aAAa,CAAC,KAAK,GAAI,aAAa,CAAC,KAAsB,EAAE,QAAQ,CAAC;KACvE;IACD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAElD,IAAI;QACF,iBAAiB,CAAC,aAAa,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;KACvC;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAClB;IAED,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5D,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE;QACrC,OAAO,CAAC,KAAK,GAAI,OAAO,CAAC,KAAsB,EAAE,QAAQ,CAAC;KAC3D;IACD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAE5C,IAAI;QACF,WAAW,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;KACjC;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAClB;IAED,MAAM,WAAW,GAAG,MAAM,iBAAiB,CACzC,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,EAChD,MAAM,CAAC,SAAS,CACjB,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAEhD,IAAI;QACF,eAAe,CAAC,WAAW,CAAC,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;KACrC;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAClB;AACH,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import fs from "fs/promises";
2
+ import { load } from "js-yaml";
3
+ import Ajv from "ajv";
4
+ // eslint-disable-next-line require-extensions/require-extensions
5
+ import schemaJson from "./schema.json";
6
+ const ajv = new Ajv({ strictTuples: false });
7
+ const validate = ajv.compile(schemaJson);
8
+ export const getConfig = async (configPath) => {
9
+ const configFile = await fs.readFile(configPath, "utf-8");
10
+ const configJson = load(configFile);
11
+ const valid = validate(load(configFile));
12
+ if (!valid) {
13
+ console.error(validate.errors);
14
+ process.exit(1);
15
+ }
16
+ const config = load(configFile);
17
+ return config;
18
+ };
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,iEAAiE;AACjE,OAAO,UAAU,MAAM,eAAe,CAAC;AAWvC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7C,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAEzC,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAE,UAAkB,EAAE,EAAE;IACpD,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IAEpC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAW,CAAC,CAAC;IAEnD,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAc,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
@@ -0,0 +1,228 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "publisher": {
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "type": "string"
9
+ },
10
+ "address": {
11
+ "type": "string"
12
+ },
13
+ "website": {
14
+ "type": "string"
15
+ },
16
+ "email": {
17
+ "type": "string"
18
+ },
19
+ "media": {
20
+ "type": "array",
21
+ "items": [
22
+ {
23
+ "type": "object",
24
+ "properties": {
25
+ "purpose": {
26
+ "type": "string"
27
+ },
28
+ "uri": {
29
+ "type": "string"
30
+ },
31
+ "width": {
32
+ "type": "integer"
33
+ },
34
+ "height": {
35
+ "type": "integer"
36
+ }
37
+ },
38
+ "required": ["purpose", "uri", "width", "height"]
39
+ }
40
+ ]
41
+ }
42
+ },
43
+ "required": ["name", "website", "email", "media"]
44
+ },
45
+ "app": {
46
+ "type": "object",
47
+ "properties": {
48
+ "name": {
49
+ "type": "string"
50
+ },
51
+ "address": {
52
+ "type": "string"
53
+ },
54
+ "android_package": {
55
+ "type": "string"
56
+ },
57
+ "creators": {
58
+ "type": "array",
59
+ "items": [
60
+ {
61
+ "type": "string"
62
+ }
63
+ ]
64
+ },
65
+ "urls": {
66
+ "type": "object",
67
+ "properties": {
68
+ "license_url": {
69
+ "type": "string"
70
+ },
71
+ "copyright_url": {
72
+ "type": "string"
73
+ },
74
+ "privacy_policy_url": {
75
+ "type": "string"
76
+ },
77
+ "website": {
78
+ "type": "string"
79
+ }
80
+ },
81
+ "required": [
82
+ "license_url",
83
+ "copyright_url",
84
+ "privacy_policy_url",
85
+ "website"
86
+ ]
87
+ },
88
+ "media": {
89
+ "type": "array",
90
+ "items": [
91
+ {
92
+ "type": "object",
93
+ "properties": {
94
+ "purpose": {
95
+ "type": "string"
96
+ },
97
+ "uri": {
98
+ "type": "string"
99
+ },
100
+ "width": {
101
+ "type": "integer"
102
+ },
103
+ "height": {
104
+ "type": "integer"
105
+ }
106
+ },
107
+ "required": ["purpose", "uri", "width", "height"]
108
+ }
109
+ ]
110
+ }
111
+ },
112
+ "required": ["name", "android_package", "creators", "urls", "media"]
113
+ },
114
+ "release": {
115
+ "type": "object",
116
+ "properties": {
117
+ "version": {
118
+ "type": "string"
119
+ },
120
+ "address": {
121
+ "type": "string"
122
+ },
123
+ "media": {
124
+ "type": "array",
125
+ "items": [
126
+ {
127
+ "type": "object",
128
+ "properties": {
129
+ "purpose": {
130
+ "type": "string"
131
+ },
132
+ "uri": {
133
+ "type": "string"
134
+ },
135
+ "width": {
136
+ "type": "integer"
137
+ },
138
+ "height": {
139
+ "type": "integer"
140
+ }
141
+ },
142
+ "required": ["purpose", "uri", "width", "height"]
143
+ }
144
+ ]
145
+ },
146
+ "files": {
147
+ "type": "array",
148
+ "minItems": 1,
149
+ "contains": {
150
+ "type": "object",
151
+ "properties": {
152
+ "purpose": {
153
+ "type": "string",
154
+ "const": "install"
155
+ }
156
+ }
157
+ },
158
+ "items": [
159
+ {
160
+ "type": "object",
161
+ "properties": {
162
+ "purpose": {
163
+ "type": "string"
164
+ },
165
+ "uri": {
166
+ "type": "string"
167
+ }
168
+ },
169
+ "required": ["purpose", "uri"]
170
+ }
171
+ ]
172
+ },
173
+ "catalog": {
174
+ "type": "object",
175
+ "properties": {
176
+ "en-US": {
177
+ "type": "object",
178
+ "properties": {
179
+ "name": {
180
+ "type": "string"
181
+ },
182
+ "short_description": {
183
+ "type": "string"
184
+ },
185
+ "long_description": {
186
+ "type": "string"
187
+ },
188
+ "new_in_version": {
189
+ "type": "string"
190
+ },
191
+ "saga_features_localized": {
192
+ "type": "string"
193
+ }
194
+ },
195
+ "required": [
196
+ "name",
197
+ "short_description",
198
+ "long_description",
199
+ "new_in_version",
200
+ "saga_features_localized"
201
+ ]
202
+ }
203
+ },
204
+ "required": ["en-US"]
205
+ }
206
+ },
207
+ "required": ["version", "media", "files", "catalog"]
208
+ },
209
+ "solana_mobile_dapp_publisher_portal": {
210
+ "type": "object",
211
+ "properties": {
212
+ "google_store_package": {
213
+ "type": "string"
214
+ },
215
+ "testing_instructions": {
216
+ "type": "string"
217
+ }
218
+ },
219
+ "required": ["google_store_package", "testing_instructions"]
220
+ }
221
+ },
222
+ "required": [
223
+ "publisher",
224
+ "app",
225
+ "release",
226
+ "solana_mobile_dapp_publisher_portal"
227
+ ]
228
+ }
@@ -0,0 +1,259 @@
1
+ import { Command } from "commander";
2
+ import { validateCommand } from "./commands/index.js";
3
+ import { createAppCommand, createPublisherCommand, createReleaseCommand } from "./commands/create/index.js";
4
+ import { publishRemoveCommand, publishSubmitCommand, publishSupportCommand, publishUpdateCommand } from "./commands/publish/index.js";
5
+ import { getConfigFile, parseKeypair, showUserErrorMessage } from "./utils.js";
6
+ import * as dotenv from "dotenv";
7
+ dotenv.config();
8
+ const hasAddressInConfig = ({ address }) => {
9
+ return !!address;
10
+ };
11
+ const program = new Command();
12
+ function resolveBuildToolsPath(buildToolsPath) {
13
+ // If a path was specified on the command line, use that
14
+ if (buildToolsPath !== undefined) {
15
+ return buildToolsPath;
16
+ }
17
+ // If a path is specified in a .env file, use that
18
+ if (process.env.ANDROID_TOOLS_DIR !== undefined) {
19
+ return process.env.ANDROID_TOOLS_DIR;
20
+ }
21
+ // No path was specified
22
+ return;
23
+ }
24
+ async function main() {
25
+ program
26
+ .name("dapp-store")
27
+ .version("0.1.0")
28
+ .description("CLI to assist with publishing to the Saga Dapp Store");
29
+ const createCommand = program
30
+ .command("create")
31
+ .description("Create a `publisher`, `app`, or `release`");
32
+ createCommand
33
+ .command("publisher")
34
+ .description("Create a publisher")
35
+ .requiredOption("-k, --keypair <path-to-keypair-file>", "Path to keypair file")
36
+ .option("-u, --url", "RPC URL", "https://devnet.genesysgo.net")
37
+ .option("-d, --dry-run", "Flag for dry run. Doesn't mint an NFT")
38
+ .action(async ({ keypair, url, dryRun }) => {
39
+ const signer = parseKeypair(keypair);
40
+ if (signer) {
41
+ const result = await createPublisherCommand({ signer, url, dryRun });
42
+ }
43
+ });
44
+ createCommand
45
+ .command("app")
46
+ .description("Create a app")
47
+ .requiredOption("-k, --keypair <path-to-keypair-file>", "Path to keypair file")
48
+ .option("-p, --publisher-mint-address <publisher-mint-address>", "The mint address of the publisher NFT")
49
+ .option("-u, --url", "RPC URL", "https://devnet.genesysgo.net")
50
+ .option("-d, --dry-run", "Flag for dry run. Doesn't mint an NFT")
51
+ .action(async ({ publisherMintAddress, keypair, url, dryRun }) => {
52
+ const config = await getConfigFile();
53
+ if (!config.isValid)
54
+ return;
55
+ if (!hasAddressInConfig(config.publisher) && !publisherMintAddress) {
56
+ showUserErrorMessage("Either specify an publisher mint address in the config file, or specify as a CLI argument to this command.");
57
+ createCommand.showHelpAfterError();
58
+ return;
59
+ }
60
+ const signer = parseKeypair(keypair);
61
+ if (signer) {
62
+ await createAppCommand({
63
+ publisherMintAddress: publisherMintAddress,
64
+ signer,
65
+ url,
66
+ dryRun,
67
+ });
68
+ }
69
+ });
70
+ createCommand
71
+ .command("release <version>")
72
+ .description("Create a release")
73
+ .requiredOption("-k, --keypair <path-to-keypair-file>", "Path to keypair file")
74
+ .option("-a, --app-mint-address <app-mint-address>", "The mint address of the app NFT")
75
+ .option("-u, --url", "RPC URL", "https://devnet.genesysgo.net")
76
+ .option("-d, --dry-run", "Flag for dry run. Doesn't mint an NFT")
77
+ .option("-b, --build-tools-path <build-tools-path>", "Path to Android build tools which contains AAPT2")
78
+ .action(async (version, { appMintAddress, keypair, url, dryRun, buildToolsPath }) => {
79
+ const toolsEnvDir = process.env.ANDROID_TOOLS_DIR ?? "";
80
+ let buildTools = "";
81
+ if (toolsEnvDir && toolsEnvDir.length > 0) {
82
+ buildTools = toolsEnvDir;
83
+ }
84
+ else if (buildToolsPath) {
85
+ buildTools = buildToolsPath;
86
+ }
87
+ else {
88
+ showUserErrorMessage("\n\n::: Please specify an Android build tools directory in the .env file or via the command line argument. :::\n\n");
89
+ createCommand.showHelpAfterError();
90
+ return;
91
+ }
92
+ const config = await getConfigFile();
93
+ if (!config.isValid)
94
+ return;
95
+ if (!hasAddressInConfig(config.app) && !appMintAddress) {
96
+ showUserErrorMessage("\n\n::: Either specify an app mint address in the config file, or specify as a CLI argument to this command. :::\n\n");
97
+ createCommand.showHelpAfterError();
98
+ return;
99
+ }
100
+ const signer = parseKeypair(keypair);
101
+ if (signer) {
102
+ const result = await createReleaseCommand({
103
+ appMintAddress: appMintAddress,
104
+ version,
105
+ buildToolsPath: buildTools,
106
+ signer,
107
+ url,
108
+ dryRun,
109
+ });
110
+ }
111
+ });
112
+ program
113
+ .command("validate")
114
+ .description("Validates details prior to publishing")
115
+ .requiredOption("-k, --keypair <path-to-keypair-file>", "Path to keypair file")
116
+ .option("-b, --build-tools-path <build-tools-path>", "Path to Android build tools which contains AAPT2")
117
+ .action(async ({ keypair, buildToolsPath }) => {
118
+ const resolvedBuildToolsPath = resolveBuildToolsPath(buildToolsPath);
119
+ if (resolvedBuildToolsPath === undefined) {
120
+ showUserErrorMessage("Please specify an Android build tools directory in the .env file or via the command line argument.");
121
+ createCommand.showHelpAfterError();
122
+ return;
123
+ }
124
+ const signer = parseKeypair(keypair);
125
+ if (signer) {
126
+ await validateCommand({
127
+ signer,
128
+ buildToolsPath: resolvedBuildToolsPath,
129
+ });
130
+ }
131
+ });
132
+ const publishCommand = program
133
+ .command("publish")
134
+ .description("Submit a publishing request (`submit`, `update`, `remove`, or `support`) to the Solana Mobile dApp publisher portal");
135
+ publishCommand
136
+ .command("submit")
137
+ .description("Submit a new app to the Solana Mobile dApp publisher portal")
138
+ .requiredOption("-k, --keypair <path-to-keypair-file>", "Path to keypair file")
139
+ .requiredOption("--complies-with-solana-dapp-store-policies", "An attestation that the app complies with the Solana dApp Store policies")
140
+ .requiredOption("--requestor-is-authorized", "An attestation that the party making this Solana dApp publisher portal request is authorized to do so")
141
+ .option("-r, --release-mint-address <release-mint-address>", "The mint address of the release NFT")
142
+ .option("-u, --url", "RPC URL", "https://devnet.genesysgo.net")
143
+ .option("-d, --dry-run", "Flag for dry run. Doesn't submit the request to the publisher portal.")
144
+ .action(async ({ releaseMintAddress, keypair, url, compliesWithSolanaDappStorePolicies, requestorIsAuthorized, dryRun, }) => {
145
+ const config = await getConfigFile();
146
+ if (!config.isValid)
147
+ return;
148
+ if (!hasAddressInConfig(config.publisher) && !releaseMintAddress) {
149
+ showUserErrorMessage("\n\n::: Either specify an release mint address in the config file, or specify as a CLI argument to this command. :::\n\n");
150
+ publishCommand.showHelpAfterError();
151
+ return;
152
+ }
153
+ const signer = parseKeypair(keypair);
154
+ if (signer) {
155
+ await publishSubmitCommand({
156
+ releaseMintAddress,
157
+ signer,
158
+ url,
159
+ dryRun,
160
+ compliesWithSolanaDappStorePolicies,
161
+ requestorIsAuthorized,
162
+ });
163
+ }
164
+ });
165
+ publishCommand
166
+ .command("update")
167
+ .description("Update an existing app on the Solana Mobile dApp publisher portal")
168
+ .requiredOption("-k, --keypair <path-to-keypair-file>", "Path to keypair file")
169
+ .requiredOption("--complies-with-solana-dapp-store-policies", "An attestation that the app complies with the Solana dApp Store policies")
170
+ .requiredOption("--requestor-is-authorized", "An attestation that the party making this Solana dApp publisher portal request is authorized to do so")
171
+ .option("-r, --release-mint-address <release-mint-address>", "The mint address of the release NFT")
172
+ .option("-c, --critical", "Flag for a critical app update request")
173
+ .option("-u, --url", "RPC URL", "https://devnet.genesysgo.net")
174
+ .option("-d, --dry-run", "Flag for dry run. Doesn't submit the request to the publisher portal.")
175
+ .action(async ({ releaseMintAddress, keypair, url, compliesWithSolanaDappStorePolicies, requestorIsAuthorized, critical, dryRun, }) => {
176
+ const config = await getConfigFile();
177
+ if (!config.isValid)
178
+ return;
179
+ if (!hasAddressInConfig(config.publisher) && !releaseMintAddress) {
180
+ showUserErrorMessage("\n\n::: Either specify an release mint address in the config file, or specify as a CLI argument to this command. :::\n\n");
181
+ publishCommand.showHelpAfterError();
182
+ return;
183
+ }
184
+ const signer = parseKeypair(keypair);
185
+ if (signer) {
186
+ await publishUpdateCommand({
187
+ releaseMintAddress,
188
+ signer,
189
+ url,
190
+ dryRun,
191
+ compliesWithSolanaDappStorePolicies,
192
+ requestorIsAuthorized,
193
+ critical,
194
+ });
195
+ }
196
+ });
197
+ publishCommand
198
+ .command("remove")
199
+ .description("Remove an existing app from the Solana Mobile dApp publisher portal")
200
+ .requiredOption("-k, --keypair <path-to-keypair-file>", "Path to keypair file")
201
+ .requiredOption("--requestor-is-authorized", "An attestation that the party making this Solana dApp publisher portal request is authorized to do so")
202
+ .option("-r, --release-mint-address <release-mint-address>", "The mint address of the release NFT")
203
+ .option("-c, --critical", "Flag for a critical app removal request")
204
+ .option("-u, --url", "RPC URL", "https://devnet.genesysgo.net")
205
+ .option("-d, --dry-run", "Flag for dry run. Doesn't submit the request to the publisher portal.")
206
+ .action(async ({ releaseMintAddress, keypair, url, requestorIsAuthorized, critical, dryRun, }) => {
207
+ const config = await getConfigFile();
208
+ if (!config.isValid)
209
+ return;
210
+ if (!hasAddressInConfig(config.publisher) && !releaseMintAddress) {
211
+ showUserErrorMessage("\n\n::: Either specify an release mint address in the config file, or specify as a CLI argument to this command. :::\n\n");
212
+ publishCommand.showHelpAfterError();
213
+ return;
214
+ }
215
+ const signer = parseKeypair(keypair);
216
+ if (signer) {
217
+ await publishRemoveCommand({
218
+ releaseMintAddress,
219
+ signer,
220
+ url,
221
+ dryRun,
222
+ requestorIsAuthorized,
223
+ critical,
224
+ });
225
+ }
226
+ });
227
+ publishCommand
228
+ .command("support <request_details>")
229
+ .description("Submit a support request for an existing app on the Solana Mobile dApp publisher portal")
230
+ .requiredOption("-k, --keypair <path-to-keypair-file>", "Path to keypair file")
231
+ .requiredOption("--requestor-is-authorized", "An attestation that the party making this Solana dApp publisher portal request is authorized to do so")
232
+ .option("-r, --release-mint-address <release-mint-address>", "The mint address of the release NFT")
233
+ .option("-u, --url", "RPC URL", "https://devnet.genesysgo.net")
234
+ .option("-d, --dry-run", "Flag for dry run. Doesn't submit the request to the publisher portal.")
235
+ .action(async (requestDetails, { releaseMintAddress, keypair, url, requestorIsAuthorized, dryRun }) => {
236
+ const config = await getConfigFile();
237
+ if (!config.isValid)
238
+ return;
239
+ if (!hasAddressInConfig(config.publisher) && !releaseMintAddress) {
240
+ showUserErrorMessage("\n\n::: Either specify an release mint address in the config file, or specify as a CLI argument to this command. :::\n\n");
241
+ publishCommand.showHelpAfterError();
242
+ return;
243
+ }
244
+ const signer = parseKeypair(keypair);
245
+ if (signer) {
246
+ await publishSupportCommand({
247
+ releaseMintAddress,
248
+ signer,
249
+ url,
250
+ dryRun,
251
+ requestorIsAuthorized,
252
+ requestDetails,
253
+ });
254
+ }
255
+ });
256
+ await program.parseAsync(process.argv);
257
+ }
258
+ main();
259
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}