@dcl/content-validator 4.0.27 → 4.1.1-20230112172753.commit-633da1a
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/the-graph-client/the-graph-client.d.ts +4 -0
- package/dist/the-graph-client/the-graph-client.d.ts.map +1 -1
- package/dist/the-graph-client/the-graph-client.js +37 -53
- package/dist/the-graph-client/the-graph-client.js.map +1 -1
- package/dist/types.d.ts +20 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/validations/access-checker/items/collection-asset.d.ts.map +1 -1
- package/dist/validations/access-checker/items/collection-asset.js +38 -106
- package/dist/validations/access-checker/items/collection-asset.js.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 +18 -79
- 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/dist/validations/timestamps.d.ts +1 -1
- package/dist/validations/timestamps.js +2 -2
- package/package.json +10 -5
- package/dist/content-validator.api.json +0 -1508
- package/dist/tsdoc-metadata.json +0 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"the-graph-client.d.ts","sourceRoot":"","sources":["../../src/the-graph-client/the-graph-client.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,0BAA0B,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"the-graph-client.d.ts","sourceRoot":"","sources":["../../src/the-graph-client/the-graph-client.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,0BAA0B,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAGvF,oBAAY,gBAAgB,GAAG;IAC7B,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB,CAAA;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM;;;EAYlD;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,eACnB,KAAK,0BAA0B,EAAE,MAAM,GAAG,WAAW,CAAC,KACjE,cAoNF,CAAA"}
|
|
@@ -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,7 +26,7 @@ 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();
|
|
@@ -78,8 +91,8 @@ const createTheGraphClient = (components) => {
|
|
|
78
91
|
return permissionOk();
|
|
79
92
|
}
|
|
80
93
|
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.
|
|
94
|
+
const ethereumItemsOwnersPromise = ownsItemsAtTimestampInBlockchain(ethAddress, ethereum, timestamp, components.subGraphs.L1.collections, components.subGraphs.l1BlockSearch);
|
|
95
|
+
const maticItemsOwnersPromise = ownsItemsAtTimestampInBlockchain(ethAddress, matic, timestamp, components.subGraphs.L2.collections, components.subGraphs.l2BlockSearch);
|
|
83
96
|
const [ethereumItemsOwnership, maticItemsOwnership] = await Promise.all([
|
|
84
97
|
ethereumItemsOwnersPromise,
|
|
85
98
|
maticItemsOwnersPromise
|
|
@@ -90,11 +103,11 @@ const createTheGraphClient = (components) => {
|
|
|
90
103
|
return permissionError([...(ethereumItemsOwnership.failing ?? []), ...(maticItemsOwnership.failing ?? [])]);
|
|
91
104
|
}
|
|
92
105
|
};
|
|
93
|
-
const ownsItemsAtTimestampInBlockchain = async (ethAddress, urnsToCheck, timestamp,
|
|
106
|
+
const ownsItemsAtTimestampInBlockchain = async (ethAddress, urnsToCheck, timestamp, collectionsSubgraph, blockSearch) => {
|
|
94
107
|
if (urnsToCheck.length === 0) {
|
|
95
108
|
return permissionOk();
|
|
96
109
|
}
|
|
97
|
-
const blocks = await findBlocksForTimestamp(
|
|
110
|
+
const blocks = await findBlocksForTimestamp(timestamp, blockSearch);
|
|
98
111
|
const hasPermissionOnBlock = async (blockNumber) => {
|
|
99
112
|
if (!blockNumber) {
|
|
100
113
|
return permissionError();
|
|
@@ -132,35 +145,25 @@ const createTheGraphClient = (components) => {
|
|
|
132
145
|
const response = await query.subgraph.query(query.query, variables);
|
|
133
146
|
return query.mapper(response);
|
|
134
147
|
};
|
|
135
|
-
const findBlocksForTimestamp = async (
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
148
|
+
const findBlocksForTimestamp = async (timestamp, blockSearch) => {
|
|
149
|
+
const { lower, upper } = timestampBounds(timestamp);
|
|
150
|
+
const result = await Promise.all([
|
|
151
|
+
blockSearch.findBlockForTimestamp(upper),
|
|
152
|
+
blockSearch.findBlockForTimestamp(lower)
|
|
153
|
+
]);
|
|
154
|
+
const blockNumberAtDeployment = result[0];
|
|
155
|
+
let blockNumberFiveMinBeforeDeployment = result[1];
|
|
156
|
+
if (blockNumberFiveMinBeforeDeployment && blockNumberFiveMinBeforeDeployment.timestamp < lower) {
|
|
157
|
+
// Mimic the way TheGraph was calculating this
|
|
158
|
+
blockNumberFiveMinBeforeDeployment = {
|
|
159
|
+
...blockNumberFiveMinBeforeDeployment,
|
|
160
|
+
block: blockNumberFiveMinBeforeDeployment.block + 1
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
blockNumberAtDeployment: blockNumberAtDeployment?.block,
|
|
165
|
+
blockNumberFiveMinBeforeDeployment: blockNumberFiveMinBeforeDeployment?.block
|
|
153
166
|
};
|
|
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
167
|
};
|
|
165
168
|
return {
|
|
166
169
|
ownsNamesAtTimestamp,
|
|
@@ -169,25 +172,6 @@ const createTheGraphClient = (components) => {
|
|
|
169
172
|
};
|
|
170
173
|
};
|
|
171
174
|
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
175
|
const QUERY_NAMES_FOR_ADDRESS_AT_BLOCK = `
|
|
192
176
|
query getNftNamesForBlock($block: Int!, $ethAddress: String!, $nameList: [String!]) {
|
|
193
177
|
names: 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/types.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
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
|
*/
|
|
@@ -94,22 +96,35 @@ 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 declare type L1Checker = {
|
|
103
|
+
checkLAND(ethAddress: string, parcels: [number, number][], block: number): Promise<boolean[]>;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* @public
|
|
107
|
+
*/
|
|
108
|
+
export declare type L2Checker = {
|
|
109
|
+
validateWearables(ethAddress: string, contractAddress: string, assetId: string, hash: string, block: number): Promise<boolean>;
|
|
110
|
+
validateThirdParty(ethAddress: string, tpId: string, root: Buffer, block: number): Promise<boolean>;
|
|
111
|
+
};
|
|
97
112
|
/**
|
|
98
113
|
* A list with all sub-graphs used for validations.
|
|
99
114
|
* @public
|
|
100
115
|
*/
|
|
101
116
|
export declare type SubGraphs = {
|
|
102
117
|
L1: {
|
|
103
|
-
|
|
104
|
-
blocks: ISubgraphComponent;
|
|
118
|
+
checker: L1Checker;
|
|
105
119
|
collections: ISubgraphComponent;
|
|
106
120
|
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
|
|
@@ -117,7 +132,7 @@ export declare type SubGraphs = {
|
|
|
117
132
|
export declare 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
|
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":"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,aAAK,cAAc,GAAG;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,oBAAY,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,eAsE9C,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,34 @@ 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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
38
|
+
let hasAccess = false;
|
|
39
|
+
try {
|
|
40
|
+
const block = await subGraphs.l2BlockSearch.findBlockForTimestamp(timestamp);
|
|
41
|
+
if (!block) {
|
|
42
|
+
throw new Error(`block not found for timestamp ${timestamp}`);
|
|
43
|
+
}
|
|
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 [hashV0, hashV1] = await calculateHashes();
|
|
49
|
+
const [hashV0Valid, hashV1Valid] = await Promise.all([
|
|
50
|
+
subGraphs.L2.checker.validateWearables(ethAddress, asset.contractAddress, asset.id, hashV0, block.block),
|
|
51
|
+
subGraphs.L2.checker.validateWearables(ethAddress, asset.contractAddress, asset.id, hashV1, block.block)
|
|
52
|
+
]);
|
|
53
|
+
hasAccess = hashV0Valid || hashV1Valid;
|
|
71
54
|
}
|
|
72
|
-
|
|
55
|
+
catch (err) {
|
|
56
|
+
logger.error(err);
|
|
57
|
+
}
|
|
58
|
+
if (!hasAccess) {
|
|
59
|
+
return (0, types_1.validationFailed)(`The provided Eth Address '${ethAddress}' does not have access to the following item: (${asset.contractAddress}, ${asset.id})`);
|
|
60
|
+
}
|
|
61
|
+
return types_1.OK;
|
|
73
62
|
}
|
|
74
63
|
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
64
|
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
65
|
}
|
|
133
|
-
return types_1.OK;
|
|
134
66
|
},
|
|
135
67
|
canValidate(asset) {
|
|
136
68
|
return asset.type === 'blockchain-collection-v1-asset' || asset.type === 'blockchain-collection-v2-asset';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-asset.js","sourceRoot":"","sources":["../../../../src/validations/access-checker/items/collection-asset.ts"],"names":[],"mappings":";;;AAAA,0CAA6C;
|
|
1
|
+
{"version":3,"file":"collection-asset.js","sourceRoot":"","sources":["../../../../src/validations/access-checker/items/collection-asset.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"third-party-asset.d.ts","sourceRoot":"","sources":["../../../../src/validations/access-checker/items/third-party-asset.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"third-party-asset.d.ts","sourceRoot":"","sources":["../../../../src/validations/access-checker/items/third-party-asset.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAazC,eAAO,MAAM,yBAAyB,EAAE,eAuCvC,CAAA"}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.thirdPartyAssetValidation = void 0;
|
|
4
4
|
const content_hash_tree_1 = require("@dcl/content-hash-tree");
|
|
5
|
-
const hashing_1 = require("@dcl/hashing");
|
|
6
5
|
const schemas_1 = require("@dcl/schemas");
|
|
7
6
|
const types_1 = require("../../../types");
|
|
8
7
|
function toHexBuffer(value) {
|
|
@@ -14,87 +13,27 @@ function toHexBuffer(value) {
|
|
|
14
13
|
function getThirdPartyId(urn) {
|
|
15
14
|
return `urn:decentraland:${urn.network}:collections-thirdparty:${urn.thirdPartyName}`;
|
|
16
15
|
}
|
|
17
|
-
async function verifyHash(metadata, merkleRoot, logger) {
|
|
18
|
-
if (!schemas_1.MerkleProof.validate(metadata.merkleProof)) {
|
|
19
|
-
logger.debug('Merkle proof is not valid', {
|
|
20
|
-
merkleProof: metadata.merkleProof
|
|
21
|
-
});
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
const merkleProof = metadata.merkleProof;
|
|
25
|
-
const generatedCrcHash = (0, hashing_1.keccak256Hash)(metadata, metadata.merkleProof.hashingKeys);
|
|
26
|
-
// The hash provided in the merkleProof for the entity MUST match the hash generated by the validator.
|
|
27
|
-
if (metadata.merkleProof.entityHash !== generatedCrcHash) {
|
|
28
|
-
logger.debug(`The hash provided in the merkleProof doesn't match the one generated by the validator`, {
|
|
29
|
-
generatedCrcHash,
|
|
30
|
-
entityHash: metadata.merkleProof.entityHash
|
|
31
|
-
});
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
// Verify if the entity belongs to the Merkle Tree.
|
|
35
|
-
const bufferedProofs = merkleProof.proof.map((value) => toHexBuffer(value));
|
|
36
|
-
const bufferedMerkleRoot = toHexBuffer(merkleRoot);
|
|
37
|
-
return (0, content_hash_tree_1.verifyProof)(merkleProof.index, merkleProof.entityHash, bufferedProofs, bufferedMerkleRoot);
|
|
38
|
-
}
|
|
39
|
-
async function getMerkleRoot(components, block, thirdPartyId) {
|
|
40
|
-
const query = `
|
|
41
|
-
query MerkleRoot($id: String!, $block: Int!) {
|
|
42
|
-
thirdParties(where: { id: $id, isApproved: true }, block: { number: $block }, first: 1) {
|
|
43
|
-
root
|
|
44
|
-
}
|
|
45
|
-
}`;
|
|
46
|
-
const result = await components.subGraphs.L2.thirdPartyRegistry.query(query, {
|
|
47
|
-
id: thirdPartyId,
|
|
48
|
-
block
|
|
49
|
-
});
|
|
50
|
-
if (!result.thirdParties || result.thirdParties.length < 1)
|
|
51
|
-
return;
|
|
52
|
-
return result.thirdParties[0]?.root;
|
|
53
|
-
}
|
|
54
|
-
async function verifyMerkleProofedEntity(components, urn, deployment, logger) {
|
|
55
|
-
// do merkle proofed entity validation, required keys are defined by the Catalyst and must be a subset of the hashingKeys from the MerkleProof to succeed
|
|
56
|
-
const metadata = deployment.entity.metadata;
|
|
57
|
-
if (!(0, schemas_1.isThirdParty)(deployment.entity.metadata)) {
|
|
58
|
-
// This should never happen as the metadata validation ran before
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
const thirdPartyId = getThirdPartyId(urn);
|
|
62
|
-
const { blockNumberAtDeployment, blockNumberFiveMinBeforeDeployment } = await components.theGraphClient.findBlocksForTimestamp(components.subGraphs.L2.blocks, deployment.entity.timestamp);
|
|
63
|
-
const merkleRoots = [];
|
|
64
|
-
const hasPermissionOnBlock = async (blockNumber) => {
|
|
65
|
-
try {
|
|
66
|
-
if (!blockNumber)
|
|
67
|
-
return false;
|
|
68
|
-
const merkleRoot = await getMerkleRoot(components, blockNumber, thirdPartyId);
|
|
69
|
-
if (!merkleRoot) {
|
|
70
|
-
logger.debug(`Merkle proof not found for given block and third party ID`, { blockNumber, thirdPartyId });
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
merkleRoots.push(merkleRoot);
|
|
74
|
-
return await verifyHash(metadata, merkleRoot, logger);
|
|
75
|
-
}
|
|
76
|
-
catch (e) {
|
|
77
|
-
const error = e?.message;
|
|
78
|
-
logger.debug(error);
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
const validMerkleProofedEntity = (await hasPermissionOnBlock(blockNumberAtDeployment)) ||
|
|
83
|
-
(await hasPermissionOnBlock(blockNumberFiveMinBeforeDeployment));
|
|
84
|
-
if (!validMerkleProofedEntity) {
|
|
85
|
-
logger.debug(`Merkle Tree based verifications failed:`, {
|
|
86
|
-
merkleProof: JSON.stringify(metadata.merkleProof),
|
|
87
|
-
merkleRoots: JSON.stringify(merkleRoots),
|
|
88
|
-
blocks: JSON.stringify([blockNumberAtDeployment, blockNumberFiveMinBeforeDeployment])
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
return validMerkleProofedEntity;
|
|
92
|
-
}
|
|
93
16
|
exports.thirdPartyAssetValidation = {
|
|
94
17
|
async validateAsset(components, asset, deployment) {
|
|
95
18
|
const logger = components.logs.getLogger('collection asset access validation');
|
|
96
|
-
|
|
97
|
-
|
|
19
|
+
const { timestamp } = deployment.entity;
|
|
20
|
+
let verified = false;
|
|
21
|
+
if ((0, schemas_1.isThirdParty)(deployment.entity.metadata)) {
|
|
22
|
+
// This should always happen as the metadata validation ran before
|
|
23
|
+
const block = await components.subGraphs.l2BlockSearch.findBlockForTimestamp(timestamp);
|
|
24
|
+
if (block) {
|
|
25
|
+
const metadata = deployment.entity.metadata;
|
|
26
|
+
const merkleProof = metadata.merkleProof;
|
|
27
|
+
const ethAddress = components.externalCalls.ownerAddress(deployment.auditInfo);
|
|
28
|
+
const thirdPartyId = getThirdPartyId(asset);
|
|
29
|
+
const bufferedProofs = merkleProof.proof.map((value) => toHexBuffer(value));
|
|
30
|
+
const root = (0, content_hash_tree_1.generateRoot)(merkleProof.index, merkleProof.entityHash, bufferedProofs);
|
|
31
|
+
verified = await components.subGraphs.L2.checker.validateThirdParty(ethAddress, thirdPartyId, root, block.block);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
logger.warn(`Cannot find block for timestamp ${timestamp}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
98
37
|
if (!verified) {
|
|
99
38
|
return (0, types_1.validationFailed)(`Couldn't verify merkle proofed entity`);
|
|
100
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"third-party-asset.js","sourceRoot":"","sources":["../../../../src/validations/access-checker/items/third-party-asset.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"third-party-asset.js","sourceRoot":"","sources":["../../../../src/validations/access-checker/items/third-party-asset.ts"],"names":[],"mappings":";;;AAAA,8DAAqD;AACrD,0CAA4D;AAE5D,0CAAuG;AAGvG,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QAC1B,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA,CAAC,mCAAmC;KAClF;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAClC,CAAC;AAED,SAAS,eAAe,CAAC,GAAmC;IAC1D,OAAO,oBAAoB,GAAG,CAAC,OAAO,2BAA2B,GAAG,CAAC,cAAc,EAAE,CAAA;AACvF,CAAC;AAEY,QAAA,yBAAyB,GAAoB;IACxD,KAAK,CAAC,aAAa,CACjB,UAAuG,EACvG,KAAqC,EACrC,UAAgC;QAEhC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAA;QAE9E,MAAM,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC,MAAM,CAAA;QACvC,IAAI,QAAQ,GAAG,KAAK,CAAA;QAEpB,IAAI,IAAA,sBAAY,EAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;YAC5C,kEAAkE;YAElE,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAA;YACvF,IAAI,KAAK,EAAE;gBACT,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,QAA2B,CAAA;gBAC9D,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAA;gBAExC,MAAM,UAAU,GAAG,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;gBAE9E,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;gBAE3C,MAAM,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAA;gBAC3E,MAAM,IAAI,GAAG,IAAA,gCAAY,EAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;gBACpF,QAAQ,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;aACjH;iBAAM;gBACL,MAAM,CAAC,IAAI,CAAC,mCAAmC,SAAS,EAAE,CAAC,CAAA;aAC5D;SACF;QAED,IAAI,CAAC,QAAQ,EAAE;YACb,OAAO,IAAA,wBAAgB,EAAC,uCAAuC,CAAC,CAAA;SACjE;QACD,OAAO,UAAE,CAAA;IACX,CAAC;IACD,WAAW,CAAC,KAAK;QACf,OAAO,KAAK,CAAC,IAAI,KAAK,mCAAmC,CAAA;IAC3D,CAAC;CACF,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenes.d.ts","sourceRoot":"","sources":["../../../src/validations/access-checker/scenes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scenes.d.ts","sourceRoot":"","sources":["../../../src/validations/access-checker/scenes.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,UAAU,EAAE,MAAM,aAAa,CAAA;AAIpD;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,UAyDpB,CAAA"}
|