@dcl/content-validator 4.2.1 → 4.2.3-20230116175244.commit-84aaedb
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/dist/content-validator.api.json +178 -53
- package/dist/the-graph-client/the-graph-client.d.ts +5 -1
- package/dist/the-graph-client/the-graph-client.d.ts.map +1 -1
- package/dist/the-graph-client/the-graph-client.js +49 -83
- package/dist/the-graph-client/the-graph-client.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types.d.ts +38 -23
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/validations/ADR51.d.ts +1 -1
- package/dist/validations/ADR51.d.ts.map +1 -1
- package/dist/validations/access-checker/items/collection-asset.d.ts +2 -2
- package/dist/validations/access-checker/items/collection-asset.d.ts.map +1 -1
- package/dist/validations/access-checker/items/collection-asset.js +43 -106
- package/dist/validations/access-checker/items/collection-asset.js.map +1 -1
- package/dist/validations/access-checker/items/items.d.ts +3 -3
- package/dist/validations/access-checker/items/items.d.ts.map +1 -1
- package/dist/validations/access-checker/items/third-party-asset.d.ts.map +1 -1
- package/dist/validations/access-checker/items/third-party-asset.js +21 -80
- package/dist/validations/access-checker/items/third-party-asset.js.map +1 -1
- package/dist/validations/access-checker/scenes.d.ts.map +1 -1
- package/dist/validations/access-checker/scenes.js +29 -227
- package/dist/validations/access-checker/scenes.js.map +1 -1
- package/package.json +9 -4
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createTheGraphClient = void 0;
|
|
3
|
+
exports.createTheGraphClient = exports.timestampBounds = void 0;
|
|
4
4
|
const urn_resolver_1 = require("@dcl/urn-resolver");
|
|
5
|
+
function timestampBounds(timestampMs) {
|
|
6
|
+
/*
|
|
7
|
+
* This mimics original behavior of looking up to 8 seconds after the entity timestamp
|
|
8
|
+
* and up to 5 minutes and 7 seconds before
|
|
9
|
+
*/
|
|
10
|
+
const timestampSec = Math.ceil(timestampMs / 1000) + 8;
|
|
11
|
+
const timestamp5MinAgo = Math.max(timestampSec - 60 * 5 - 7, 0);
|
|
12
|
+
return {
|
|
13
|
+
upper: timestampSec,
|
|
14
|
+
lower: timestamp5MinAgo
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
exports.timestampBounds = timestampBounds;
|
|
5
18
|
/**
|
|
6
19
|
* @public
|
|
7
20
|
*/
|
|
@@ -13,27 +26,19 @@ const createTheGraphClient = (components) => {
|
|
|
13
26
|
if (namesToCheck.length === 0) {
|
|
14
27
|
return permissionOk();
|
|
15
28
|
}
|
|
16
|
-
const blocks = await findBlocksForTimestamp(components.subGraphs.
|
|
29
|
+
const blocks = await findBlocksForTimestamp(timestamp, components.subGraphs.l1BlockSearch);
|
|
17
30
|
const hasPermissionOnBlock = async (blockNumber) => {
|
|
18
31
|
if (!blockNumber) {
|
|
19
32
|
return permissionError();
|
|
20
33
|
}
|
|
21
|
-
const runOwnedNamesOnBlockQuery = async (blockNumber) => {
|
|
22
|
-
const query = {
|
|
23
|
-
description: 'check for names ownership',
|
|
24
|
-
subgraph: components.subGraphs.L1.ensOwner,
|
|
25
|
-
query: QUERY_NAMES_FOR_ADDRESS_AT_BLOCK,
|
|
26
|
-
mapper: (response) => new Set(response.names.map(({ name }) => name))
|
|
27
|
-
};
|
|
28
|
-
return runQuery(query, {
|
|
29
|
-
block: blockNumber,
|
|
30
|
-
ethAddress,
|
|
31
|
-
nameList: namesToCheck
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
34
|
try {
|
|
35
|
-
const
|
|
36
|
-
const notOwned =
|
|
35
|
+
const result = await components.subGraphs.L1.checker.checkNames(ethAddress, namesToCheck, blockNumber);
|
|
36
|
+
const notOwned = [];
|
|
37
|
+
for (let i = 0; i < namesToCheck.length; i++) {
|
|
38
|
+
if (!result[i]) {
|
|
39
|
+
notOwned.push(namesToCheck[i]);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
37
42
|
return notOwned.length > 0 ? permissionError(notOwned) : permissionOk();
|
|
38
43
|
}
|
|
39
44
|
catch {
|
|
@@ -41,11 +46,11 @@ const createTheGraphClient = (components) => {
|
|
|
41
46
|
return permissionError();
|
|
42
47
|
}
|
|
43
48
|
};
|
|
44
|
-
const permissionMostRecentBlock = await hasPermissionOnBlock(blocks.
|
|
49
|
+
const permissionMostRecentBlock = await hasPermissionOnBlock(blocks.blockAtDeployment);
|
|
45
50
|
if (permissionMostRecentBlock.result) {
|
|
46
51
|
return permissionMostRecentBlock;
|
|
47
52
|
}
|
|
48
|
-
return await hasPermissionOnBlock(blocks.
|
|
53
|
+
return await hasPermissionOnBlock(blocks.blockFiveMinBeforeDeployment);
|
|
49
54
|
};
|
|
50
55
|
const splitItemsByNetwork = async (urnsToCheck) => {
|
|
51
56
|
const ethereum = [];
|
|
@@ -78,8 +83,8 @@ const createTheGraphClient = (components) => {
|
|
|
78
83
|
return permissionOk();
|
|
79
84
|
}
|
|
80
85
|
const { ethereum, matic } = await splitItemsByNetwork(urnsToCheck);
|
|
81
|
-
const ethereumItemsOwnersPromise = ownsItemsAtTimestampInBlockchain(ethAddress, ethereum, timestamp, components.subGraphs.L1.
|
|
82
|
-
const maticItemsOwnersPromise = ownsItemsAtTimestampInBlockchain(ethAddress, matic, timestamp, components.subGraphs.L2.
|
|
86
|
+
const ethereumItemsOwnersPromise = ownsItemsAtTimestampInBlockchain(ethAddress, ethereum, timestamp, components.subGraphs.L1.collections, components.subGraphs.l1BlockSearch);
|
|
87
|
+
const maticItemsOwnersPromise = ownsItemsAtTimestampInBlockchain(ethAddress, matic, timestamp, components.subGraphs.L2.collections, components.subGraphs.l2BlockSearch);
|
|
83
88
|
const [ethereumItemsOwnership, maticItemsOwnership] = await Promise.all([
|
|
84
89
|
ethereumItemsOwnersPromise,
|
|
85
90
|
maticItemsOwnersPromise
|
|
@@ -90,11 +95,11 @@ const createTheGraphClient = (components) => {
|
|
|
90
95
|
return permissionError([...(ethereumItemsOwnership.failing ?? []), ...(maticItemsOwnership.failing ?? [])]);
|
|
91
96
|
}
|
|
92
97
|
};
|
|
93
|
-
const ownsItemsAtTimestampInBlockchain = async (ethAddress, urnsToCheck, timestamp,
|
|
98
|
+
const ownsItemsAtTimestampInBlockchain = async (ethAddress, urnsToCheck, timestamp, collectionsSubgraph, blockSearch) => {
|
|
94
99
|
if (urnsToCheck.length === 0) {
|
|
95
100
|
return permissionOk();
|
|
96
101
|
}
|
|
97
|
-
const blocks = await findBlocksForTimestamp(
|
|
102
|
+
const blocks = await findBlocksForTimestamp(timestamp, blockSearch);
|
|
98
103
|
const hasPermissionOnBlock = async (blockNumber) => {
|
|
99
104
|
if (!blockNumber) {
|
|
100
105
|
return permissionError();
|
|
@@ -118,49 +123,39 @@ const createTheGraphClient = (components) => {
|
|
|
118
123
|
return notOwned.length > 0 ? permissionError(notOwned) : permissionOk();
|
|
119
124
|
}
|
|
120
125
|
catch (error) {
|
|
121
|
-
logger.error(`Error retrieving items owned by address ${ethAddress} at block ${blocks.
|
|
126
|
+
logger.error(`Error retrieving items owned by address ${ethAddress} at block ${blocks.blockAtDeployment}`);
|
|
122
127
|
return permissionError();
|
|
123
128
|
}
|
|
124
129
|
};
|
|
125
|
-
const permissionMostRecentBlock = await hasPermissionOnBlock(blocks.
|
|
130
|
+
const permissionMostRecentBlock = await hasPermissionOnBlock(blocks.blockAtDeployment);
|
|
126
131
|
if (permissionMostRecentBlock.result) {
|
|
127
132
|
return permissionMostRecentBlock;
|
|
128
133
|
}
|
|
129
|
-
return await hasPermissionOnBlock(blocks.
|
|
134
|
+
return await hasPermissionOnBlock(blocks.blockFiveMinBeforeDeployment);
|
|
130
135
|
};
|
|
131
136
|
const runQuery = async (query, variables) => {
|
|
132
137
|
const response = await query.subgraph.query(query.query, variables);
|
|
133
138
|
return query.mapper(response);
|
|
134
139
|
};
|
|
135
|
-
const findBlocksForTimestamp = async (
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
140
|
+
const findBlocksForTimestamp = async (timestamp, blockSearch) => {
|
|
141
|
+
const { lower, upper } = timestampBounds(timestamp);
|
|
142
|
+
const result = await Promise.all([
|
|
143
|
+
blockSearch.findBlockForTimestamp(upper),
|
|
144
|
+
blockSearch.findBlockForTimestamp(lower)
|
|
145
|
+
]);
|
|
146
|
+
const blockNumberAtDeployment = result[0];
|
|
147
|
+
let blockNumberFiveMinBeforeDeployment = result[1];
|
|
148
|
+
if (blockNumberFiveMinBeforeDeployment && blockNumberFiveMinBeforeDeployment.timestamp < lower) {
|
|
149
|
+
// Mimic the way TheGraph was calculating this
|
|
150
|
+
blockNumberFiveMinBeforeDeployment = {
|
|
151
|
+
...blockNumberFiveMinBeforeDeployment,
|
|
152
|
+
block: blockNumberFiveMinBeforeDeployment.block + 1
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
blockAtDeployment: blockNumberAtDeployment?.block,
|
|
157
|
+
blockFiveMinBeforeDeployment: blockNumberFiveMinBeforeDeployment?.block
|
|
153
158
|
};
|
|
154
|
-
/*
|
|
155
|
-
* This mimics original behavior of looking up to 8 seconds after the entity timestamp
|
|
156
|
-
* and up to 5 minutes and 7 seconds before
|
|
157
|
-
*/
|
|
158
|
-
const timestampSec = Math.ceil(timestamp / 1000) + 8;
|
|
159
|
-
const timestamp5MinAgo = timestampSec - 60 * 5 - 7;
|
|
160
|
-
return await runQuery(query, {
|
|
161
|
-
timestamp: timestampSec,
|
|
162
|
-
timestamp5Min: timestamp5MinAgo
|
|
163
|
-
});
|
|
164
159
|
};
|
|
165
160
|
return {
|
|
166
161
|
ownsNamesAtTimestamp,
|
|
@@ -169,35 +164,6 @@ const createTheGraphClient = (components) => {
|
|
|
169
164
|
};
|
|
170
165
|
};
|
|
171
166
|
exports.createTheGraphClient = createTheGraphClient;
|
|
172
|
-
const QUERY_BLOCKS_FOR_TIMESTAMP = `
|
|
173
|
-
query getBlockForTimestampRange($timestamp: Int!, $timestamp5Min: Int!) {
|
|
174
|
-
min: blocks(
|
|
175
|
-
where: {timestamp_gte: $timestamp5Min, timestamp_lte: $timestamp}
|
|
176
|
-
first: 1
|
|
177
|
-
orderBy: timestamp
|
|
178
|
-
orderDirection: desc
|
|
179
|
-
) {
|
|
180
|
-
number
|
|
181
|
-
}
|
|
182
|
-
max: blocks(
|
|
183
|
-
where: {timestamp_gte: $timestamp5Min, timestamp_lte: $timestamp}
|
|
184
|
-
first: 1
|
|
185
|
-
orderBy: timestamp
|
|
186
|
-
orderDirection: asc
|
|
187
|
-
) {
|
|
188
|
-
number
|
|
189
|
-
}
|
|
190
|
-
}`;
|
|
191
|
-
const QUERY_NAMES_FOR_ADDRESS_AT_BLOCK = `
|
|
192
|
-
query getNftNamesForBlock($block: Int!, $ethAddress: String!, $nameList: [String!]) {
|
|
193
|
-
names: nfts(
|
|
194
|
-
block: {number: $block}
|
|
195
|
-
where: {owner: $ethAddress, category: ens, name_in: $nameList}
|
|
196
|
-
first: 1000
|
|
197
|
-
) {
|
|
198
|
-
name
|
|
199
|
-
}
|
|
200
|
-
}`;
|
|
201
167
|
const QUERY_ITEMS_FOR_ADDRESS_AT_BLOCK = `
|
|
202
168
|
query getNftItemsForBlock($block: Int!, $ethAddress: String!, $urnList: [String!]) {
|
|
203
169
|
items: nfts(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"the-graph-client.js","sourceRoot":"","sources":["../../src/the-graph-client/the-graph-client.ts"],"names":[],"mappings":";;;AACA,oDAA4C;
|
|
1
|
+
{"version":3,"file":"the-graph-client.js","sourceRoot":"","sources":["../../src/the-graph-client/the-graph-client.ts"],"names":[],"mappings":"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"}
|
package/dist/tsdoc-metadata.json
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -1,32 +1,34 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { AuthChain, Entity, EthAddress } from '@dcl/schemas';
|
|
2
3
|
import { IConfigComponent, ILoggerComponent } from '@well-known-components/interfaces';
|
|
3
4
|
import { ISubgraphComponent, Variables } from '@well-known-components/thegraph-component';
|
|
4
5
|
import { PermissionResult } from './the-graph-client/the-graph-client';
|
|
6
|
+
import { BlockSearch } from '@dcl/block-indexer';
|
|
5
7
|
/**
|
|
6
8
|
* @public
|
|
7
9
|
*/
|
|
8
|
-
export
|
|
10
|
+
export type LocalDeploymentAuditInfo = {
|
|
9
11
|
authChain: AuthChain;
|
|
10
12
|
};
|
|
11
13
|
/**
|
|
12
14
|
* @public
|
|
13
15
|
*/
|
|
14
|
-
export
|
|
16
|
+
export type Errors = string[];
|
|
15
17
|
/**
|
|
16
18
|
* @public
|
|
17
19
|
*/
|
|
18
|
-
export
|
|
20
|
+
export type Warnings = string[];
|
|
19
21
|
/**
|
|
20
22
|
* @public
|
|
21
23
|
*/
|
|
22
|
-
export
|
|
24
|
+
export type EntityWithEthAddress = Entity & {
|
|
23
25
|
ethAddress: string;
|
|
24
26
|
};
|
|
25
27
|
/**
|
|
26
28
|
* Deployment object to be validated by the validator.
|
|
27
29
|
* @public
|
|
28
30
|
*/
|
|
29
|
-
export
|
|
31
|
+
export type DeploymentToValidate = {
|
|
30
32
|
entity: Entity;
|
|
31
33
|
files: Map<string, Uint8Array>;
|
|
32
34
|
auditInfo: LocalDeploymentAuditInfo;
|
|
@@ -35,12 +37,12 @@ export declare type DeploymentToValidate = {
|
|
|
35
37
|
* Function used to fetch TheGraph
|
|
36
38
|
* @public
|
|
37
39
|
*/
|
|
38
|
-
export
|
|
40
|
+
export type QueryGraph = <T = any>(query: string, variables?: Variables, remainingAttempts?: number) => Promise<T>;
|
|
39
41
|
/**
|
|
40
42
|
* External calls interface to be provided by the servers.
|
|
41
43
|
* @public
|
|
42
44
|
*/
|
|
43
|
-
export
|
|
45
|
+
export type ExternalCalls = {
|
|
44
46
|
isContentStoredAlready: (hashes: string[]) => Promise<Map<string, boolean>>;
|
|
45
47
|
fetchContentFileSize: (hash: string) => Promise<number | undefined>;
|
|
46
48
|
validateSignature: (entityId: string, auditInfo: LocalDeploymentAuditInfo, timestamp: number) => Promise<{
|
|
@@ -60,26 +62,26 @@ export interface Validator {
|
|
|
60
62
|
/**
|
|
61
63
|
* @public
|
|
62
64
|
*/
|
|
63
|
-
export
|
|
65
|
+
export type ValidationArgs = {
|
|
64
66
|
deployment: DeploymentToValidate;
|
|
65
67
|
};
|
|
66
68
|
/**
|
|
67
69
|
* @public
|
|
68
70
|
*/
|
|
69
|
-
export
|
|
71
|
+
export type ValidationResponse = {
|
|
70
72
|
ok: boolean;
|
|
71
73
|
errors?: Errors;
|
|
72
74
|
};
|
|
73
75
|
/**
|
|
74
76
|
* @public
|
|
75
77
|
*/
|
|
76
|
-
export
|
|
78
|
+
export type Validation = {
|
|
77
79
|
validate: (components: ContentValidatorComponents, deployment: DeploymentToValidate) => ValidationResponse | Promise<ValidationResponse>;
|
|
78
80
|
};
|
|
79
81
|
/**
|
|
80
82
|
* @public
|
|
81
83
|
*/
|
|
82
|
-
export
|
|
84
|
+
export type ConditionalValidation = {
|
|
83
85
|
predicate: (components: ContentValidatorComponents, deployment: DeploymentToValidate) => ValidationResponse | Promise<ValidationResponse>;
|
|
84
86
|
};
|
|
85
87
|
/**
|
|
@@ -94,43 +96,56 @@ export declare const validationFailed: (...error: string[]) => ValidationRespons
|
|
|
94
96
|
* @public
|
|
95
97
|
*/
|
|
96
98
|
export declare const fromErrors: (...errors: Errors) => ValidationResponse;
|
|
99
|
+
/**
|
|
100
|
+
* @public
|
|
101
|
+
*/
|
|
102
|
+
export type L1Checker = {
|
|
103
|
+
checkLAND(ethAddress: string, parcels: [number, number][], block: number): Promise<boolean[]>;
|
|
104
|
+
checkNames(ethAddress: string, names: string[], block: number): Promise<boolean[]>;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* @public
|
|
108
|
+
*/
|
|
109
|
+
export type L2Checker = {
|
|
110
|
+
validateWearables(ethAddress: string, contractAddress: string, assetId: string, hash: string, block: number): Promise<boolean>;
|
|
111
|
+
validateThirdParty(ethAddress: string, tpId: string, root: Buffer, block: number): Promise<boolean>;
|
|
112
|
+
};
|
|
97
113
|
/**
|
|
98
114
|
* A list with all sub-graphs used for validations.
|
|
99
115
|
* @public
|
|
100
116
|
*/
|
|
101
|
-
export
|
|
117
|
+
export type SubGraphs = {
|
|
102
118
|
L1: {
|
|
103
|
-
|
|
104
|
-
blocks: ISubgraphComponent;
|
|
119
|
+
checker: L1Checker;
|
|
105
120
|
collections: ISubgraphComponent;
|
|
106
|
-
ensOwner: ISubgraphComponent;
|
|
107
121
|
};
|
|
108
122
|
L2: {
|
|
109
|
-
|
|
123
|
+
checker: L2Checker;
|
|
110
124
|
collections: ISubgraphComponent;
|
|
111
|
-
thirdPartyRegistry: ISubgraphComponent;
|
|
112
125
|
};
|
|
126
|
+
l1BlockSearch: BlockSearch;
|
|
127
|
+
l2BlockSearch: BlockSearch;
|
|
113
128
|
};
|
|
114
129
|
/**
|
|
115
130
|
* @public
|
|
116
131
|
*/
|
|
117
|
-
export
|
|
132
|
+
export type TheGraphClient = {
|
|
118
133
|
ownsNamesAtTimestamp: (ethAddress: EthAddress, namesToCheck: string[], timestamp: number) => Promise<PermissionResult>;
|
|
119
134
|
ownsItemsAtTimestamp: (ethAddress: EthAddress, urnsToCheck: string[], timestamp: number) => Promise<PermissionResult>;
|
|
120
|
-
findBlocksForTimestamp: (
|
|
135
|
+
findBlocksForTimestamp: (timestamp: number, blockSearch: BlockSearch) => Promise<BlockInformation>;
|
|
121
136
|
};
|
|
122
137
|
/**
|
|
123
138
|
* @public
|
|
124
139
|
*/
|
|
125
|
-
export
|
|
126
|
-
|
|
127
|
-
|
|
140
|
+
export type BlockInformation = {
|
|
141
|
+
blockAtDeployment: number | undefined;
|
|
142
|
+
blockFiveMinBeforeDeployment: number | undefined;
|
|
128
143
|
};
|
|
129
144
|
/**
|
|
130
145
|
* Components that can be used to validate deployments.
|
|
131
146
|
* @public
|
|
132
147
|
*/
|
|
133
|
-
export
|
|
148
|
+
export type ContentValidatorComponents = {
|
|
134
149
|
config: IConfigComponent;
|
|
135
150
|
logs: ILoggerComponent;
|
|
136
151
|
theGraphClient: TheGraphClient;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AACtF,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAA;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAuGA;;GAEG;AACU,QAAA,EAAE,GAAuB,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;AAElD;;GAEG;AACI,MAAM,gBAAgB,GAAG,CAAC,GAAG,KAAe,EAAsB,EAAE,CAAC,CAAC;IAC3E,EAAE,EAAE,KAAK;IACT,MAAM,EAAE,KAAK;CACd,CAAC,CAAA;AAHW,QAAA,gBAAgB,oBAG3B;AAEF;;GAEG;AACI,MAAM,UAAU,GAAG,CAAC,GAAG,MAAc,EAAsB,EAAE,CAAC,CAAC;IACpE,EAAE,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;CAC/C,CAAC,CAAA;AAHW,QAAA,UAAU,cAGrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ADR51.d.ts","sourceRoot":"","sources":["../../src/validations/ADR51.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEnG,
|
|
1
|
+
{"version":3,"file":"ADR51.d.ts","sourceRoot":"","sources":["../../src/validations/ADR51.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEnG,KAAK,MAAM,GAAG;IACZ,QAAQ,EAAE,gBAAgB,CAAC,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC,CAAA;IACtE,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAqBvD,CAAA"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { AssetValidation } from './items';
|
|
2
|
-
|
|
2
|
+
type CollectionItem = {
|
|
3
3
|
managers: string[];
|
|
4
4
|
contentHash: string;
|
|
5
5
|
};
|
|
6
|
-
export
|
|
6
|
+
export type ItemCollection = {
|
|
7
7
|
creator: string;
|
|
8
8
|
managers: string[];
|
|
9
9
|
isApproved: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-asset.d.ts","sourceRoot":"","sources":["../../../../src/validations/access-checker/items/collection-asset.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"collection-asset.d.ts","sourceRoot":"","sources":["../../../../src/validations/access-checker/items/collection-asset.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAKzC,KAAK,cAAc,GAAG;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,UAAU,EAAE,OAAO,CAAA;IACnB,WAAW,EAAE,OAAO,CAAA;IACpB,KAAK,EAAE,cAAc,EAAE,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,gCAAgC,EAAE,eA+E9C,CAAA"}
|
|
@@ -5,51 +5,22 @@ const hashing_1 = require("@dcl/hashing");
|
|
|
5
5
|
const types_1 = require("../../../types");
|
|
6
6
|
const L1_NETWORKS = ['mainnet', 'kovan', 'rinkeby', 'goerli'];
|
|
7
7
|
const L2_NETWORKS = ['matic', 'mumbai'];
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
accounts(where:{ isCommitteeMember: true }, block: { number: $block }) {
|
|
23
|
-
id
|
|
24
|
-
}
|
|
25
|
-
}`;
|
|
26
|
-
const result = await subgraph.query(query, {
|
|
27
|
-
collection,
|
|
28
|
-
itemId: `${collection}-${itemId}`,
|
|
29
|
-
block
|
|
30
|
-
});
|
|
31
|
-
const collectionResult = result.collections[0];
|
|
32
|
-
const itemResult = collectionResult?.items[0];
|
|
33
|
-
return {
|
|
34
|
-
collectionCreator: collectionResult?.creator,
|
|
35
|
-
collectionManagers: collectionResult?.managers,
|
|
36
|
-
isApproved: collectionResult?.isApproved,
|
|
37
|
-
isCompleted: collectionResult?.isCompleted,
|
|
38
|
-
itemManagers: itemResult?.managers,
|
|
39
|
-
contentHash: itemResult?.contentHash,
|
|
40
|
-
committee: result.accounts.map(({ id }) => id.toLowerCase())
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
async function hasPermission(components, subgraph, collection, itemId, block, entity, logger) {
|
|
44
|
-
try {
|
|
45
|
-
const { content, metadata } = entity;
|
|
46
|
-
const permissions = await getCollectionItems(components, subgraph, collection, itemId, block);
|
|
47
|
-
const ethAddressLowercase = entity.ethAddress.toLowerCase();
|
|
48
|
-
if (!!permissions.contentHash) {
|
|
49
|
-
const deployedByCommittee = permissions.committee.includes(ethAddressLowercase);
|
|
50
|
-
if (!deployedByCommittee) {
|
|
51
|
-
logger.debug(`The eth address ${ethAddressLowercase} is not part of committee.`);
|
|
8
|
+
exports.v1andV2collectionAssetValidation = {
|
|
9
|
+
async validateAsset(components, asset, deployment) {
|
|
10
|
+
const { externalCalls, subGraphs } = components;
|
|
11
|
+
const ethAddress = externalCalls.ownerAddress(deployment.auditInfo);
|
|
12
|
+
const logger = components.logs.getLogger('collection asset access validation');
|
|
13
|
+
const network = asset.network;
|
|
14
|
+
if (L1_NETWORKS.includes(network)) {
|
|
15
|
+
// L1 collections are deployed by Decentraland Address
|
|
16
|
+
const isAllowlistedCollection = asset.uri.toString().startsWith('urn:decentraland:ethereum:collections-v1');
|
|
17
|
+
if (!externalCalls.isAddressOwnedByDecentraland(ethAddress) || !isAllowlistedCollection) {
|
|
18
|
+
return (0, types_1.validationFailed)(`The provided Eth Address '${ethAddress}' does not have access to the following item: '${asset.uri}'`);
|
|
52
19
|
}
|
|
20
|
+
return types_1.OK;
|
|
21
|
+
}
|
|
22
|
+
else if (L2_NETWORKS.includes(network)) {
|
|
23
|
+
const { timestamp, content, metadata } = deployment.entity;
|
|
53
24
|
const calculateHashes = () => {
|
|
54
25
|
// Compare both by key and hash
|
|
55
26
|
const compare = (a, b) => {
|
|
@@ -64,73 +35,39 @@ async function hasPermission(components, subgraph, collection, itemId, block, en
|
|
|
64
35
|
const buffer = Buffer.from(JSON.stringify({ content: contentAsJson, metadata }));
|
|
65
36
|
return Promise.all([(0, hashing_1.hashV0)(buffer), (0, hashing_1.hashV1)(buffer)]);
|
|
66
37
|
};
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
38
|
+
const validateWearable = async (hash, block) => {
|
|
39
|
+
return subGraphs.L2.checker.validateWearables(ethAddress, asset.contractAddress, asset.id, hash, block);
|
|
40
|
+
};
|
|
41
|
+
let hasAccess = false;
|
|
42
|
+
try {
|
|
43
|
+
const { blockAtDeployment, blockFiveMinBeforeDeployment } = await components.theGraphClient.findBlocksForTimestamp(timestamp, components.subGraphs.l2BlockSearch);
|
|
44
|
+
// NOTE(hugo): I'm calculating both hashes so I can make one RPC request (they are processed together as a batch),
|
|
45
|
+
// this may not be the right call, since it's possible to argue that a
|
|
46
|
+
// hash call is more expensive than a RPC call, but since I have no
|
|
47
|
+
// data to make a better decision, I think this is good enough
|
|
48
|
+
const hashes = await calculateHashes();
|
|
49
|
+
const batch = [];
|
|
50
|
+
for (const hash of hashes) {
|
|
51
|
+
if (blockAtDeployment) {
|
|
52
|
+
batch.push(validateWearable(hash, blockAtDeployment));
|
|
53
|
+
}
|
|
54
|
+
if (blockFiveMinBeforeDeployment) {
|
|
55
|
+
batch.push(validateWearable(hash, blockFiveMinBeforeDeployment));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
hasAccess = (await Promise.all(batch)).some((r) => r);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
logger.error(err);
|
|
62
|
+
}
|
|
63
|
+
if (!hasAccess) {
|
|
64
|
+
return (0, types_1.validationFailed)(`The provided Eth Address '${ethAddress}' does not have access to the following item: (${asset.contractAddress}, ${asset.id})`);
|
|
71
65
|
}
|
|
72
|
-
return
|
|
66
|
+
return types_1.OK;
|
|
73
67
|
}
|
|
74
68
|
else {
|
|
75
|
-
const addressHasAccess = (permissions.collectionCreator && permissions.collectionCreator === ethAddressLowercase) ||
|
|
76
|
-
(permissions.collectionManagers && permissions.collectionManagers.includes(ethAddressLowercase)) ||
|
|
77
|
-
(permissions.itemManagers && permissions.itemManagers.includes(ethAddressLowercase));
|
|
78
|
-
// Deployments to the content server are made after the collection is completed, so that the committee can then approve it.
|
|
79
|
-
// That's why isCompleted must be true, but isApproved must be false. After the committee approves the wearable, there can't be any more changes
|
|
80
|
-
const isCollectionValid = !permissions.isApproved && permissions.isCompleted;
|
|
81
|
-
return addressHasAccess && isCollectionValid;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
catch (error) {
|
|
85
|
-
logger.error(`Error checking permission for (${collection}-${itemId}) at block ${block}. Error: ${error}`);
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
async function checkCollectionAccess(components, blocksSubgraph, collectionsSubgraph, collection, itemId, entity, logger) {
|
|
90
|
-
const { timestamp } = entity;
|
|
91
|
-
try {
|
|
92
|
-
const { blockNumberAtDeployment, blockNumberFiveMinBeforeDeployment } = await components.theGraphClient.findBlocksForTimestamp(blocksSubgraph, timestamp);
|
|
93
|
-
// It could happen that the subgraph hasn't synced yet, so someone who just lost access still managed to make a deployment. The problem would be that when other catalysts perform
|
|
94
|
-
// the same check, the subgraph might have synced and the deployment is no longer valid. So, in order to prevent inconsistencies between catalysts, we will allow all deployments that
|
|
95
|
-
// have access now, or had access 5 minutes ago.
|
|
96
|
-
const hasPermissionOnBlock = async (blockNumber) => !!blockNumber &&
|
|
97
|
-
(await hasPermission(components, collectionsSubgraph, collection, itemId, blockNumber, entity, logger));
|
|
98
|
-
return ((await hasPermissionOnBlock(blockNumberAtDeployment)) ||
|
|
99
|
-
(await hasPermissionOnBlock(blockNumberFiveMinBeforeDeployment)));
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
logger.error(`Error checking wearable access (${collection}, ${itemId}, ${entity.ethAddress}, ${timestamp}, ${blocksSubgraph}). Error: ${error}`);
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
exports.v1andV2collectionAssetValidation = {
|
|
107
|
-
async validateAsset(components, asset, deployment) {
|
|
108
|
-
const { externalCalls, subGraphs } = components;
|
|
109
|
-
const ethAddress = externalCalls.ownerAddress(deployment.auditInfo);
|
|
110
|
-
const logger = components.logs.getLogger('collection asset access validation');
|
|
111
|
-
// L1 or L2 so contractAddress is present
|
|
112
|
-
const collection = asset.contractAddress;
|
|
113
|
-
const network = asset.network;
|
|
114
|
-
const isL1 = L1_NETWORKS.includes(network);
|
|
115
|
-
const isL2 = L2_NETWORKS.includes(network);
|
|
116
|
-
if (!isL1 && !isL2)
|
|
117
69
|
return (0, types_1.validationFailed)(`Found an unknown network on the urn '${network}'`);
|
|
118
|
-
const blocksSubgraphUrl = isL1 ? subGraphs.L1.blocks : subGraphs.L2.blocks;
|
|
119
|
-
const collectionsSubgraphUrl = isL1 ? subGraphs.L1.collections : subGraphs.L2.collections;
|
|
120
|
-
const hasAccess = await checkCollectionAccess(components, blocksSubgraphUrl, collectionsSubgraphUrl, collection, asset.id, {
|
|
121
|
-
...deployment.entity,
|
|
122
|
-
ethAddress
|
|
123
|
-
}, logger);
|
|
124
|
-
if (!hasAccess) {
|
|
125
|
-
if (isL2)
|
|
126
|
-
return (0, types_1.validationFailed)(`The provided Eth Address '${ethAddress}' does not have access to the following item: (${asset.contractAddress}, ${asset.id})`);
|
|
127
|
-
// L1 collections are deployed by Decentraland Address
|
|
128
|
-
const isAllowlistedCollection = asset.uri.toString().startsWith('urn:decentraland:ethereum:collections-v1');
|
|
129
|
-
if (!externalCalls.isAddressOwnedByDecentraland(ethAddress) || !isAllowlistedCollection) {
|
|
130
|
-
return (0, types_1.validationFailed)(`The provided Eth Address '${ethAddress}' does not have access to the following item: '${asset.uri}'`);
|
|
131
|
-
}
|
|
132
70
|
}
|
|
133
|
-
return types_1.OK;
|
|
134
71
|
},
|
|
135
72
|
canValidate(asset) {
|
|
136
73
|
return asset.type === 'blockchain-collection-v1-asset' || asset.type === 'blockchain-collection-v2-asset';
|