@solana-mobile/dapp-store-publishing-tools 0.16.0 → 1.0.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 (53) hide show
  1. package/lib/CoreUtils.js +0 -3
  2. package/lib/index.js +1 -0
  3. package/lib/portal/attestation.js +189 -0
  4. package/lib/portal/compat.js +3 -0
  5. package/lib/portal/index.js +5 -0
  6. package/lib/portal/signer.js +432 -0
  7. package/lib/portal/types.js +1 -0
  8. package/lib/portal/workflow/contracts.js +1 -0
  9. package/lib/portal/workflow/execution.js +493 -0
  10. package/lib/portal/workflow/ingestion.js +265 -0
  11. package/lib/portal/workflow/lifecycle.js +616 -0
  12. package/lib/portal/workflow/logging.js +8 -0
  13. package/lib/portal/workflow/source/files.js +304 -0
  14. package/lib/portal/workflow/source/preparation.js +318 -0
  15. package/lib/portal/workflow/state/bundle.js +260 -0
  16. package/lib/portal/workflow/state/checkpoints.js +53 -0
  17. package/lib/portal/workflow/state/session.js +100 -0
  18. package/lib/portal/workflow.js +1 -0
  19. package/lib/publish/PublishCoreAttestation.js +18 -17
  20. package/lib/publish/PublishCoreRemove.js +7 -89
  21. package/lib/publish/PublishCoreSubmit.js +7 -117
  22. package/lib/publish/PublishCoreSupport.js +7 -86
  23. package/lib/publish/PublishCoreUpdate.js +7 -117
  24. package/lib/publish/index.js +1 -0
  25. package/lib/schemas/releaseJsonMetadata.json +1 -2
  26. package/package.json +2 -4
  27. package/src/CoreUtils.ts +0 -6
  28. package/src/index.ts +1 -0
  29. package/src/portal/attestation.ts +76 -0
  30. package/src/portal/compat.ts +5 -0
  31. package/src/portal/index.ts +5 -0
  32. package/src/portal/signer.ts +327 -0
  33. package/src/portal/types.ts +447 -0
  34. package/src/portal/workflow/contracts.ts +108 -0
  35. package/src/portal/workflow/execution.ts +412 -0
  36. package/src/portal/workflow/ingestion.ts +187 -0
  37. package/src/portal/workflow/lifecycle.ts +435 -0
  38. package/src/portal/workflow/logging.ts +17 -0
  39. package/src/portal/workflow/source/files.ts +49 -0
  40. package/src/portal/workflow/source/preparation.ts +189 -0
  41. package/src/portal/workflow/state/bundle.ts +193 -0
  42. package/src/portal/workflow/state/checkpoints.ts +70 -0
  43. package/src/portal/workflow/state/session.ts +87 -0
  44. package/src/portal/workflow.ts +9 -0
  45. package/src/publish/PublishCoreAttestation.ts +21 -26
  46. package/src/publish/PublishCoreRemove.ts +13 -109
  47. package/src/publish/PublishCoreSubmit.ts +18 -150
  48. package/src/publish/PublishCoreSupport.ts +13 -102
  49. package/src/publish/PublishCoreUpdate.ts +17 -155
  50. package/src/publish/index.ts +2 -1
  51. package/src/schemas/releaseJsonMetadata.json +1 -2
  52. package/lib/publish/dapp_publisher_portal.js +0 -206
  53. package/src/publish/dapp_publisher_portal.ts +0 -81
@@ -1,161 +1,29 @@
1
- import { Connection } from "@solana/web3.js";
2
- import type { Publisher, SolanaMobileDappPublisherPortal } from "../types.js";
3
- import { createAttestationPayload } from "./PublishCoreAttestation.js";
4
- import {
5
- CONTACT_OBJECT_ID,
6
- CONTACT_PROPERTY_COMPANY,
7
- CONTACT_PROPERTY_EMAIL,
8
- CONTACT_PROPERTY_WEBSITE,
9
- submitRequestToSolanaDappPublisherPortal,
10
- TICKET_OBJECT_ID,
11
- TICKET_PROPERTY_ALPHA_TEST,
12
- TICKET_PROPERTY_ALPHA_TESTERS,
13
- TICKET_PROPERTY_ATTESTATION_PAYLOAD,
14
- TICKET_PROPERTY_AUTHORIZED_REQUEST,
15
- TICKET_PROPERTY_DAPP_COLLECTION_ACCOUNT_ADDRESS,
16
- TICKET_PROPERTY_DAPP_RELEASE_ACCOUNT_ADDRESS,
17
- TICKET_PROPERTY_GOOGLE_PLAY_STORE_PACKAGE_NAME,
18
- TICKET_PROPERTY_POLICY_COMPLIANT,
19
- TICKET_PROPERTY_REQUEST_UNIQUE_ID,
20
- TICKET_PROPERTY_TESTING_INSTRUCTIONS,
21
- URL_FORM_SUBMIT
22
- } from "./dapp_publisher_portal.js";
23
- import { PublishSolanaNetworkInput, SignWithPublisherKeypair } from "./types.js";
24
-
25
- const createSubmitRequest = async (
26
- connection: Connection,
27
- sign: SignWithPublisherKeypair,
28
- appMintAddress: string,
29
- releaseMintAddress: string,
30
- publisherDetails: Publisher,
31
- solanaMobileDappPublisherPortalDetails: SolanaMobileDappPublisherPortal,
32
- compliesWithSolanaDappStorePolicies: boolean,
33
- requestorIsAuthorized: boolean,
34
- alphaTest?: boolean
35
- ) => {
36
- const { attestationPayload, requestUniqueId } = await createAttestationPayload(connection, sign);
37
-
38
- const request = {
39
- fields: [
40
- {
41
- objectTypeId: CONTACT_OBJECT_ID,
42
- name: CONTACT_PROPERTY_COMPANY,
43
- value: publisherDetails.name
44
- },
45
- {
46
- objectTypeId: CONTACT_OBJECT_ID,
47
- name: CONTACT_PROPERTY_EMAIL,
48
- value: publisherDetails.email
49
- },
50
- {
51
- objectTypeId: CONTACT_OBJECT_ID,
52
- name: CONTACT_PROPERTY_WEBSITE,
53
- value: publisherDetails.website
54
- },
55
- {
56
- objectTypeId: TICKET_OBJECT_ID,
57
- name: TICKET_PROPERTY_ATTESTATION_PAYLOAD,
58
- value: attestationPayload
59
- },
60
- {
61
- objectTypeId: TICKET_OBJECT_ID,
62
- name: TICKET_PROPERTY_DAPP_COLLECTION_ACCOUNT_ADDRESS,
63
- value: appMintAddress
64
- },
65
- {
66
- objectTypeId: TICKET_OBJECT_ID,
67
- name: TICKET_PROPERTY_DAPP_RELEASE_ACCOUNT_ADDRESS,
68
- value: releaseMintAddress
69
- },
70
- {
71
- objectTypeId: TICKET_OBJECT_ID,
72
- name: TICKET_PROPERTY_REQUEST_UNIQUE_ID,
73
- value: requestUniqueId
74
- },
75
- {
76
- objectTypeId: TICKET_OBJECT_ID,
77
- name: TICKET_PROPERTY_AUTHORIZED_REQUEST,
78
- value: requestorIsAuthorized
79
- },
80
- {
81
- objectTypeId: TICKET_OBJECT_ID,
82
- name: TICKET_PROPERTY_POLICY_COMPLIANT,
83
- value: compliesWithSolanaDappStorePolicies
84
- }
85
- ]
86
- };
87
-
88
- if (solanaMobileDappPublisherPortalDetails.google_store_package !== undefined) {
89
- request.fields.push({
90
- objectTypeId: TICKET_OBJECT_ID,
91
- name: TICKET_PROPERTY_GOOGLE_PLAY_STORE_PACKAGE_NAME,
92
- value: solanaMobileDappPublisherPortalDetails.google_store_package
93
- });
94
- }
95
-
96
- if (alphaTest) {
97
- request.fields.push({
98
- objectTypeId: TICKET_OBJECT_ID,
99
- name: TICKET_PROPERTY_ALPHA_TEST,
100
- value: true,
101
- });
102
- }
103
-
104
- if (solanaMobileDappPublisherPortalDetails.testing_instructions !== undefined) {
105
- request.fields.push(
106
- {
107
- objectTypeId: TICKET_OBJECT_ID,
108
- name: TICKET_PROPERTY_TESTING_INSTRUCTIONS,
109
- value: solanaMobileDappPublisherPortalDetails.testing_instructions
110
- },
111
- );
112
- }
113
-
114
- if (solanaMobileDappPublisherPortalDetails.alpha_testers !== undefined && solanaMobileDappPublisherPortalDetails.alpha_testers.length > 0) {
115
- request.fields.push({
116
- objectTypeId: TICKET_OBJECT_ID,
117
- name: TICKET_PROPERTY_ALPHA_TESTERS,
118
- value: solanaMobileDappPublisherPortalDetails.alpha_testers.map(tester => tester.address).toString(),
119
- });
120
- }
121
-
122
- return request;
123
- };
1
+ import { deprecateLegacyPublishSurface } from '../portal/compat.js';
2
+ import type { PublishSolanaNetworkInput } from './types.js';
124
3
 
125
4
  export type PublishSubmitInput = {
126
5
  appMintAddress: string;
127
6
  releaseMintAddress: string;
128
- publisherDetails: Publisher;
129
- solanaMobileDappPublisherPortalDetails: SolanaMobileDappPublisherPortal;
7
+ publisherDetails: {
8
+ name: string;
9
+ website: string;
10
+ email: string;
11
+ };
12
+ solanaMobileDappPublisherPortalDetails: {
13
+ google_store_package?: string;
14
+ testing_instructions?: string;
15
+ alpha_testers?: Array<{ address: string; comment: string }>;
16
+ };
130
17
  compliesWithSolanaDappStorePolicies: boolean;
131
18
  requestorIsAuthorized: boolean;
132
19
  alphaTest?: boolean;
133
20
  };
134
21
 
135
22
  export const publishSubmit = async (
136
- publishSolanaNetworkInput: PublishSolanaNetworkInput,
137
- {
138
- appMintAddress,
139
- releaseMintAddress,
140
- publisherDetails,
141
- solanaMobileDappPublisherPortalDetails,
142
- compliesWithSolanaDappStorePolicies,
143
- requestorIsAuthorized,
144
- alphaTest,
145
- } : PublishSubmitInput,
146
- dryRun: boolean,
147
- ) => {
148
- const submitRequest = await createSubmitRequest(
149
- publishSolanaNetworkInput.connection,
150
- publishSolanaNetworkInput.sign,
151
- appMintAddress,
152
- releaseMintAddress,
153
- publisherDetails,
154
- solanaMobileDappPublisherPortalDetails,
155
- compliesWithSolanaDappStorePolicies,
156
- requestorIsAuthorized,
157
- alphaTest
158
- );
159
-
160
- return submitRequestToSolanaDappPublisherPortal(submitRequest, URL_FORM_SUBMIT, dryRun);
23
+ _publishSolanaNetworkInput: PublishSolanaNetworkInput,
24
+ _input: PublishSubmitInput,
25
+ _dryRun: boolean,
26
+ ): Promise<never> => {
27
+ deprecateLegacyPublishSurface('publishSubmit');
28
+ return undefined as never;
161
29
  };
@@ -1,112 +1,23 @@
1
- import { Connection } from "@solana/web3.js";
2
- import type { Publisher } from "../types.js";
3
- import { createAttestationPayload } from "./PublishCoreAttestation.js";
4
- import {
5
- CONTACT_OBJECT_ID,
6
- CONTACT_PROPERTY_COMPANY,
7
- CONTACT_PROPERTY_EMAIL,
8
- CONTACT_PROPERTY_WEBSITE,
9
- submitRequestToSolanaDappPublisherPortal,
10
- TICKET_OBJECT_ID,
11
- TICKET_PROPERTY_ATTESTATION_PAYLOAD,
12
- TICKET_PROPERTY_AUTHORIZED_REQUEST,
13
- TICKET_PROPERTY_CONTENT,
14
- TICKET_PROPERTY_DAPP_COLLECTION_ACCOUNT_ADDRESS,
15
- TICKET_PROPERTY_DAPP_RELEASE_ACCOUNT_ADDRESS,
16
- TICKET_PROPERTY_REQUEST_UNIQUE_ID,
17
- URL_FORM_SUPPORT
18
- } from "./dapp_publisher_portal.js";
19
- import { PublishSolanaNetworkInput, SignWithPublisherKeypair } from "./types.js";
20
-
21
- const createSupportRequest = async (
22
- connection: Connection,
23
- sign: SignWithPublisherKeypair,
24
- appMintAddress: string,
25
- releaseMintAddress: string,
26
- publisherDetails: Publisher,
27
- requestorIsAuthorized: boolean,
28
- requestDetails: string
29
- ) => {
30
- const { attestationPayload, requestUniqueId } = await createAttestationPayload(connection, sign);
31
-
32
- return {
33
- fields: [
34
- {
35
- objectTypeId: CONTACT_OBJECT_ID,
36
- name: CONTACT_PROPERTY_COMPANY,
37
- value: publisherDetails.name
38
- },
39
- {
40
- objectTypeId: CONTACT_OBJECT_ID,
41
- name: CONTACT_PROPERTY_EMAIL,
42
- value: publisherDetails.email
43
- },
44
- {
45
- objectTypeId: CONTACT_OBJECT_ID,
46
- name: CONTACT_PROPERTY_WEBSITE,
47
- value: publisherDetails.website
48
- },
49
- {
50
- objectTypeId: TICKET_OBJECT_ID,
51
- name: TICKET_PROPERTY_ATTESTATION_PAYLOAD,
52
- value: attestationPayload
53
- },
54
- {
55
- objectTypeId: TICKET_OBJECT_ID,
56
- name: TICKET_PROPERTY_CONTENT,
57
- value: requestDetails
58
- },
59
- {
60
- objectTypeId: TICKET_OBJECT_ID,
61
- name: TICKET_PROPERTY_DAPP_COLLECTION_ACCOUNT_ADDRESS,
62
- value: appMintAddress
63
- },
64
- {
65
- objectTypeId: TICKET_OBJECT_ID,
66
- name: TICKET_PROPERTY_DAPP_RELEASE_ACCOUNT_ADDRESS,
67
- value: releaseMintAddress
68
- },
69
- {
70
- objectTypeId: TICKET_OBJECT_ID,
71
- name: TICKET_PROPERTY_REQUEST_UNIQUE_ID,
72
- value: requestUniqueId
73
- },
74
- {
75
- objectTypeId: TICKET_OBJECT_ID,
76
- name: TICKET_PROPERTY_AUTHORIZED_REQUEST,
77
- value: requestorIsAuthorized
78
- }
79
- ]
80
- };
81
- };
1
+ import { deprecateLegacyPublishSurface } from '../portal/compat.js';
2
+ import type { PublishSolanaNetworkInput } from './types.js';
82
3
 
83
4
  export type PublishSupportInput = {
84
5
  appMintAddress: string;
85
6
  releaseMintAddress: string;
86
- publisherDetails: Publisher;
7
+ publisherDetails: {
8
+ name: string;
9
+ website: string;
10
+ email: string;
11
+ };
87
12
  requestorIsAuthorized: boolean;
88
13
  requestDetails: string;
89
14
  };
90
15
 
91
16
  export const publishSupport = async (
92
- publishSolanaNetworkInput: PublishSolanaNetworkInput,
93
- {
94
- appMintAddress,
95
- releaseMintAddress,
96
- publisherDetails,
97
- requestorIsAuthorized,
98
- requestDetails,
99
- } : PublishSupportInput,
100
- dryRun: boolean,
101
- ) => {
102
- const supportRequest = await createSupportRequest(
103
- publishSolanaNetworkInput.connection,
104
- publishSolanaNetworkInput.sign,
105
- appMintAddress,
106
- releaseMintAddress,
107
- publisherDetails,
108
- requestorIsAuthorized,
109
- requestDetails);
110
-
111
- return submitRequestToSolanaDappPublisherPortal(supportRequest, URL_FORM_SUPPORT, dryRun);
17
+ _publishSolanaNetworkInput: PublishSolanaNetworkInput,
18
+ _input: PublishSupportInput,
19
+ _dryRun: boolean,
20
+ ): Promise<never> => {
21
+ deprecateLegacyPublishSurface('publishSupport');
22
+ return undefined as never;
112
23
  };
@@ -1,135 +1,18 @@
1
- import { Connection } from "@solana/web3.js";
2
- import type { Publisher, SolanaMobileDappPublisherPortal } from "../types.js";
3
- import { createAttestationPayload } from "./PublishCoreAttestation.js";
4
- import {
5
- CONTACT_OBJECT_ID,
6
- CONTACT_PROPERTY_COMPANY,
7
- CONTACT_PROPERTY_EMAIL,
8
- CONTACT_PROPERTY_WEBSITE,
9
- submitRequestToSolanaDappPublisherPortal,
10
- TICKET_OBJECT_ID,
11
- TICKET_PROPERTY_ALPHA_TEST,
12
- TICKET_PROPERTY_ALPHA_TESTERS,
13
- TICKET_PROPERTY_ATTESTATION_PAYLOAD,
14
- TICKET_PROPERTY_AUTHORIZED_REQUEST,
15
- TICKET_PROPERTY_CRITICAL_UPDATE,
16
- TICKET_PROPERTY_DAPP_COLLECTION_ACCOUNT_ADDRESS,
17
- TICKET_PROPERTY_DAPP_RELEASE_ACCOUNT_ADDRESS,
18
- TICKET_PROPERTY_POLICY_COMPLIANT,
19
- TICKET_PROPERTY_REQUEST_UNIQUE_ID,
20
- TICKET_PROPERTY_TESTING_INSTRUCTIONS,
21
- URL_FORM_UPDATE
22
- } from "./dapp_publisher_portal.js";
23
- import { PublishSolanaNetworkInput, SignWithPublisherKeypair } from "./types.js";
24
-
25
- const createUpdateRequest = async (
26
- connection: Connection,
27
- sign: SignWithPublisherKeypair,
28
- appMintAddress: string,
29
- releaseMintAddress: string,
30
- publisherDetails: Publisher,
31
- solanaMobileDappPublisherPortalDetails: SolanaMobileDappPublisherPortal,
32
- compliesWithSolanaDappStorePolicies: boolean,
33
- requestorIsAuthorized: boolean,
34
- criticalUpdate: boolean,
35
- alphaTest?: boolean
36
- ) => {
37
- const { attestationPayload, requestUniqueId } = await createAttestationPayload(connection, sign);
38
-
39
- const request = {
40
- fields: [
41
- {
42
- objectTypeId: CONTACT_OBJECT_ID,
43
- name: CONTACT_PROPERTY_COMPANY,
44
- value: publisherDetails.name
45
- },
46
- {
47
- objectTypeId: CONTACT_OBJECT_ID,
48
- name: CONTACT_PROPERTY_EMAIL,
49
- value: publisherDetails.email
50
- },
51
- {
52
- objectTypeId: CONTACT_OBJECT_ID,
53
- name: CONTACT_PROPERTY_WEBSITE,
54
- value: publisherDetails.website
55
- },
56
- {
57
- objectTypeId: TICKET_OBJECT_ID,
58
- name: TICKET_PROPERTY_ATTESTATION_PAYLOAD,
59
- value: attestationPayload
60
- },
61
- {
62
- objectTypeId: TICKET_OBJECT_ID,
63
- name: TICKET_PROPERTY_DAPP_COLLECTION_ACCOUNT_ADDRESS,
64
- value: appMintAddress
65
- },
66
- {
67
- objectTypeId: TICKET_OBJECT_ID,
68
- name: TICKET_PROPERTY_DAPP_RELEASE_ACCOUNT_ADDRESS,
69
- value: releaseMintAddress
70
- },
71
- {
72
- objectTypeId: TICKET_OBJECT_ID,
73
- name: TICKET_PROPERTY_REQUEST_UNIQUE_ID,
74
- value: requestUniqueId
75
- },
76
- {
77
- objectTypeId: TICKET_OBJECT_ID,
78
- name: TICKET_PROPERTY_AUTHORIZED_REQUEST,
79
- value: requestorIsAuthorized
80
- },
81
- {
82
- objectTypeId: TICKET_OBJECT_ID,
83
- name: TICKET_PROPERTY_POLICY_COMPLIANT,
84
- value: compliesWithSolanaDappStorePolicies
85
- }
86
- ]
87
- };
88
-
89
- if (criticalUpdate) {
90
- request.fields.push(
91
- {
92
- objectTypeId: TICKET_OBJECT_ID,
93
- name: TICKET_PROPERTY_CRITICAL_UPDATE,
94
- value: criticalUpdate
95
- }
96
- );
97
- }
98
-
99
- if (alphaTest) {
100
- request.fields.push({
101
- objectTypeId: TICKET_OBJECT_ID,
102
- name: TICKET_PROPERTY_ALPHA_TEST,
103
- value: true,
104
- });
105
- }
106
-
107
- if (solanaMobileDappPublisherPortalDetails.testing_instructions !== undefined) {
108
- request.fields.push(
109
- {
110
- objectTypeId: TICKET_OBJECT_ID,
111
- name: TICKET_PROPERTY_TESTING_INSTRUCTIONS,
112
- value: solanaMobileDappPublisherPortalDetails.testing_instructions
113
- }
114
- );
115
- }
116
-
117
- if (solanaMobileDappPublisherPortalDetails.alpha_testers !== undefined && solanaMobileDappPublisherPortalDetails.alpha_testers.length > 0) {
118
- request.fields.push({
119
- objectTypeId: TICKET_OBJECT_ID,
120
- name: TICKET_PROPERTY_ALPHA_TESTERS,
121
- value: solanaMobileDappPublisherPortalDetails.alpha_testers.map(tester => tester.address).toString(),
122
- });
123
- }
124
-
125
- return request;
126
- };
1
+ import { deprecateLegacyPublishSurface } from '../portal/compat.js';
2
+ import type { PublishSolanaNetworkInput } from './types.js';
127
3
 
128
4
  export type PublishUpdateInput = {
129
5
  appMintAddress: string;
130
6
  releaseMintAddress: string;
131
- publisherDetails: Publisher;
132
- solanaMobileDappPublisherPortalDetails: SolanaMobileDappPublisherPortal;
7
+ publisherDetails: {
8
+ name: string;
9
+ website: string;
10
+ email: string;
11
+ };
12
+ solanaMobileDappPublisherPortalDetails: {
13
+ testing_instructions?: string;
14
+ alpha_testers?: Array<{ address: string; comment: string }>;
15
+ };
133
16
  compliesWithSolanaDappStorePolicies: boolean;
134
17
  requestorIsAuthorized: boolean;
135
18
  criticalUpdate: boolean;
@@ -137,31 +20,10 @@ export type PublishUpdateInput = {
137
20
  };
138
21
 
139
22
  export const publishUpdate = async (
140
- publishSolanaNetworkInput: PublishSolanaNetworkInput,
141
- {
142
- appMintAddress,
143
- releaseMintAddress,
144
- publisherDetails,
145
- solanaMobileDappPublisherPortalDetails,
146
- compliesWithSolanaDappStorePolicies,
147
- requestorIsAuthorized,
148
- criticalUpdate,
149
- alphaTest,
150
- } : PublishUpdateInput,
151
- dryRun: boolean,
152
- ) => {
153
- const updateRequest = await createUpdateRequest(
154
- publishSolanaNetworkInput.connection,
155
- publishSolanaNetworkInput.sign,
156
- appMintAddress,
157
- releaseMintAddress,
158
- publisherDetails,
159
- solanaMobileDappPublisherPortalDetails,
160
- compliesWithSolanaDappStorePolicies,
161
- requestorIsAuthorized,
162
- criticalUpdate,
163
- alphaTest
164
- );
165
-
166
- return submitRequestToSolanaDappPublisherPortal(updateRequest, URL_FORM_UPDATE, dryRun);
23
+ _publishSolanaNetworkInput: PublishSolanaNetworkInput,
24
+ _input: PublishUpdateInput,
25
+ _dryRun: boolean,
26
+ ): Promise<never> => {
27
+ deprecateLegacyPublishSurface('publishUpdate');
28
+ return undefined as never;
167
29
  };
@@ -1,5 +1,6 @@
1
+ export * from "./PublishCoreAttestation.js";
1
2
  export * from "./PublishCoreRemove.js";
2
3
  export * from "./PublishCoreSubmit.js";
3
4
  export * from "./PublishCoreSupport.js";
4
5
  export * from "./types.js";
5
- export * from "./PublishCoreUpdate.js";
6
+ export * from "./PublishCoreUpdate.js";
@@ -72,8 +72,7 @@
72
72
  "pattern": "^https://"
73
73
  },
74
74
  "copyright_url": {
75
- "type": "string",
76
- "pattern": "^https://"
75
+ "type": "string"
77
76
  },
78
77
  "privacy_policy_url": {
79
78
  "type": "string",