@eluvio/elv-client-js 3.2.16 → 3.2.20
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/ElvWalletClient-min.js +9 -9
- package/dist/ElvWalletClient-node-min.js +10 -10
- package/dist/src/walletClient/ClientMethods.js +793 -481
- package/dist/src/walletClient/Configuration.js +2 -0
- package/dist/src/walletClient/Profile.js +368 -0
- package/dist/src/walletClient/Utils.js +33 -29
- package/dist/src/walletClient/index.js +86 -62
- package/package.json +1 -1
- package/src/walletClient/ClientMethods.js +151 -13
- package/src/walletClient/Configuration.js +3 -0
- package/src/walletClient/Profile.js +182 -0
- package/src/walletClient/Utils.js +29 -24
- package/src/walletClient/index.js +125 -26
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
let WalletConfiguration = {
|
|
2
2
|
demo: {
|
|
3
3
|
configUrl: "https://demov3.net955210.contentfabric.io/config",
|
|
4
|
+
stateStoreUrls: ["https://appsvc.svc.eluv.io/dv3"],
|
|
4
5
|
staging: {
|
|
5
6
|
siteId: "iq__2gkNh8CCZqFFnoRpEUmz7P3PaBQG",
|
|
6
7
|
purchaseMode: "develop",
|
|
@@ -9,6 +10,7 @@ let WalletConfiguration = {
|
|
|
9
10
|
},
|
|
10
11
|
main: {
|
|
11
12
|
configUrl: "https://main.net955305.contentfabric.io/config",
|
|
13
|
+
stateStoreUrls: ["https://appsvc.svc.eluv.io/main"],
|
|
12
14
|
staging: {
|
|
13
15
|
siteId: "iq__inauxD1KLyKWPHargCWjdCh2ayr",
|
|
14
16
|
purchaseMode: "production",
|
|
@@ -21,6 +23,7 @@ let WalletConfiguration = {
|
|
|
21
23
|
}
|
|
22
24
|
},
|
|
23
25
|
__MARKETPLACE_ORDER: [
|
|
26
|
+
"PREVIEW",
|
|
24
27
|
"dolly-marketplace",
|
|
25
28
|
"oc-marketplace",
|
|
26
29
|
"maskverse-marketplace",
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
const Utils = require("../Utils");
|
|
2
|
+
const UrlJoin = require("url-join");
|
|
3
|
+
|
|
4
|
+
const StateStorePath = ({network, path}) => {
|
|
5
|
+
return UrlJoin(network === "main" ? "/main" : "/dv3", path);
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const UserProfilePath = ({network, appId, userAddress, key, type, mode}) => {
|
|
9
|
+
return StateStorePath({network, path: UrlJoin(type === "app" ? "app" : "usr", type === "app" ? appId : "", userAddress, mode === "public" ? "pub" : "pri", key || "")});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Methods related to getting and setting user profile data.
|
|
14
|
+
*
|
|
15
|
+
* @module ProfileMethods
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Retrieve user profile metadata for the specified user
|
|
20
|
+
*
|
|
21
|
+
* @methodGroup ProfileMetadata
|
|
22
|
+
* @namedParams
|
|
23
|
+
* @param {string=} type="app" - Specify `app` or `user` metadata.
|
|
24
|
+
* @param {string=} mode="public" - Specify `public` or `private` metadata. If private is specified, you may only retrieve metadata for the current user.
|
|
25
|
+
* @param {string=} appId - Namespace to use for the metadata, if retrieving app metadata. Uses the app ID specified on client initialization by default.
|
|
26
|
+
* @param {string=} userAddress - User to retrieve metadata for. If not specified, will retrieve metadata for the current user
|
|
27
|
+
* @param {string=} key - The metadata key to retrieve
|
|
28
|
+
*
|
|
29
|
+
* @returns {Promise<Object|String>} - Returns the specified metadata
|
|
30
|
+
*/
|
|
31
|
+
exports.ProfileMetadata = async function({type="app", mode="public", appId, userAddress, key}) {
|
|
32
|
+
try {
|
|
33
|
+
const response = await this.stateStoreClient.Request({
|
|
34
|
+
path: UserProfilePath({
|
|
35
|
+
network: this.network,
|
|
36
|
+
appId: appId || this.appId,
|
|
37
|
+
userAddress: userAddress || this.UserAddress(),
|
|
38
|
+
type,
|
|
39
|
+
mode,
|
|
40
|
+
key
|
|
41
|
+
}),
|
|
42
|
+
headers: mode === "private" ?
|
|
43
|
+
{Authorization: `Bearer ${this.AuthToken()}`} : undefined
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if(!response.ok) {
|
|
47
|
+
throw response;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return (await Utils.ResponseToJson(response))[key];
|
|
51
|
+
} catch(error) {
|
|
52
|
+
if(error.status === 404) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Set user profile metadata for the current user
|
|
62
|
+
*
|
|
63
|
+
* @methodGroup ProfileMetadata
|
|
64
|
+
* @namedParams
|
|
65
|
+
* @param {string=} type="app" - Specify `app` or `user` metadata.
|
|
66
|
+
* @param {string=} mode="public" - Specify `public` or `private` metadata.
|
|
67
|
+
* @param {string=} appId - Namespace to use for the metadata, if retrieving app metadata. Uses the app ID specified on client initialization by default.
|
|
68
|
+
* @param {string} key - The metadata key to set
|
|
69
|
+
* @param {string} value - The metadata value to set
|
|
70
|
+
*/
|
|
71
|
+
exports.SetProfileMetadata = async function({type="app", mode="public", appId, key, value}) {
|
|
72
|
+
await this.stateStoreClient.Request({
|
|
73
|
+
method: "POST",
|
|
74
|
+
path: UserProfilePath({
|
|
75
|
+
network: this.network,
|
|
76
|
+
appId: appId || this.appId,
|
|
77
|
+
userAddress: this.UserAddress(),
|
|
78
|
+
type,
|
|
79
|
+
mode,
|
|
80
|
+
key
|
|
81
|
+
}),
|
|
82
|
+
body: value,
|
|
83
|
+
bodyType: typeof value === "object" ? "JSON" : "string",
|
|
84
|
+
headers: {
|
|
85
|
+
Authorization: `Bearer ${this.AuthToken()}`
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Remove user profile metadata for the current user
|
|
93
|
+
*
|
|
94
|
+
* @methodGroup ProfileMetadata
|
|
95
|
+
* @namedParams
|
|
96
|
+
* @param {string=} type="app" - Specify `app` or `user` metadata.
|
|
97
|
+
* @param {string=} mode="public" - Specify `public` or `private` metadata.
|
|
98
|
+
* @param {string=} appId - Namespace to use for the metadata, if retrieving app metadata.. Uses the app ID specified on client initialization by default.
|
|
99
|
+
* @param {string} key - The metadata key to set
|
|
100
|
+
* @param {string} value - The metadata value to set
|
|
101
|
+
*/
|
|
102
|
+
exports.RemoveProfileMetadata = async function({type="app", mode="public", appId, key, value}) {
|
|
103
|
+
await this.stateStoreClient.Request({
|
|
104
|
+
method: "DELETE",
|
|
105
|
+
path: UserProfilePath({
|
|
106
|
+
network: this.network,
|
|
107
|
+
appId: appId || this.appId,
|
|
108
|
+
userAddress: this.UserAddress(),
|
|
109
|
+
type,
|
|
110
|
+
mode,
|
|
111
|
+
key
|
|
112
|
+
}),
|
|
113
|
+
body: value,
|
|
114
|
+
headers: {
|
|
115
|
+
Authorization: `Bearer ${this.AuthToken()}`
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Retrieve profile info for the specified user, including address, username and profile image (if set)
|
|
122
|
+
*
|
|
123
|
+
* @methodGroup Profile
|
|
124
|
+
* @param {string=} userAddress - Address of the user
|
|
125
|
+
* @param {string=} userName - Username of the user
|
|
126
|
+
*
|
|
127
|
+
* @returns {Promise<Object>} - Profile info of the specified user
|
|
128
|
+
*/
|
|
129
|
+
exports.Profile = async function({userAddress, userName}) {
|
|
130
|
+
if(userName) {
|
|
131
|
+
userAddress = await this.UserNameToAddress({userName});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if(!userAddress) {
|
|
135
|
+
throw Error("Eluvio Wallet Client: Unable to determine profile - user address not specified");
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if(!userName) {
|
|
139
|
+
userName = await this.ProfileMetadata({type: "user", userAddress, key: "username"});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const imageUrl = await this.ProfileMetadata({type: "user", userAddress, key: "icon_url"});
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
userAddress: Utils.FormatAddress(userAddress),
|
|
146
|
+
userName,
|
|
147
|
+
imageUrl
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
exports.UserNameToAddress = async function({userName}) {
|
|
152
|
+
try {
|
|
153
|
+
const response = await this.stateStoreClient.Request({
|
|
154
|
+
method: "GET",
|
|
155
|
+
path: StateStorePath({network: this.network, path: UrlJoin("usr", "profile_for_username", userName)}),
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
if(!response.ok) {
|
|
159
|
+
throw response;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return (await Utils.ResponseToJson(response)).address;
|
|
163
|
+
} catch(error) {
|
|
164
|
+
if(error.status !== 404) {
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return undefined;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
@@ -23,6 +23,24 @@ const RarityToPercentage = (rarity) => {
|
|
|
23
23
|
return percentage;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
const LinkTargetHash = function(link) {
|
|
27
|
+
if(!link) { return; }
|
|
28
|
+
|
|
29
|
+
if(link["."] && link["."].source) {
|
|
30
|
+
return link["."].source;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if(link["/"] && link["/"].startsWith("/qfab/")) {
|
|
34
|
+
return link["/"].split("/").find(segment => segment.startsWith("hq__"));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if(link["."] && link["."].container) {
|
|
38
|
+
return link["."].container;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
exports.LinkTargetHash = LinkTargetHash;
|
|
43
|
+
|
|
26
44
|
// Format NFT or listing result into consistent format
|
|
27
45
|
const FormatNFTDetails = function(entry) {
|
|
28
46
|
const isListing = !!entry.id;
|
|
@@ -70,7 +88,7 @@ const FormatNFTDetails = function(entry) {
|
|
|
70
88
|
exports.FormatNFTDetails = FormatNFTDetails;
|
|
71
89
|
|
|
72
90
|
|
|
73
|
-
const FormatNFTMetadata = function(nft) {
|
|
91
|
+
const FormatNFTMetadata = function(walletClient, nft) {
|
|
74
92
|
nft.formatted = true;
|
|
75
93
|
|
|
76
94
|
// Surface relevant details to top level
|
|
@@ -105,10 +123,13 @@ const FormatNFTMetadata = function(nft) {
|
|
|
105
123
|
|
|
106
124
|
let embedUrl = new URL("https://embed.v3.contentfabric.io");
|
|
107
125
|
embedUrl.searchParams.set("p", "");
|
|
108
|
-
embedUrl.searchParams.set("net",
|
|
109
|
-
embedUrl.searchParams.set("ath", rootStore.authToken);
|
|
126
|
+
embedUrl.searchParams.set("net", walletClient.network === "demo" ? "demo" : "main");
|
|
110
127
|
|
|
111
|
-
if(
|
|
128
|
+
if(media.requires_permissions) {
|
|
129
|
+
embedUrl.searchParams.set("ath", walletClient.AuthToken());
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if(["video", "audio"].includes(mediaType)) {
|
|
112
133
|
embedUrl.searchParams.set("vid", LinkTargetHash(media.media_link));
|
|
113
134
|
embedUrl.searchParams.set("ct", "h");
|
|
114
135
|
embedUrl.searchParams.set("ap", "");
|
|
@@ -123,6 +144,7 @@ const FormatNFTMetadata = function(nft) {
|
|
|
123
144
|
embed_url: embedUrl.toString()
|
|
124
145
|
};
|
|
125
146
|
} catch(error) {
|
|
147
|
+
walletClient.Log(error, true);
|
|
126
148
|
return media;
|
|
127
149
|
}
|
|
128
150
|
});
|
|
@@ -134,8 +156,7 @@ const FormatNFTMetadata = function(nft) {
|
|
|
134
156
|
if(nft.metadata.pack_options && nft.metadata.pack_options[key]) {
|
|
135
157
|
let embedUrl = new URL("https://embed.v3.contentfabric.io");
|
|
136
158
|
embedUrl.searchParams.set("p", "");
|
|
137
|
-
embedUrl.searchParams.set("net",
|
|
138
|
-
embedUrl.searchParams.set("ath", rootStore.authToken || rootStore.staticToken);
|
|
159
|
+
embedUrl.searchParams.set("net", walletClient.network === "demo" ? "demo" : "main");
|
|
139
160
|
embedUrl.searchParams.set("vid", LinkTargetHash(nft.metadata.pack_options[key]));
|
|
140
161
|
embedUrl.searchParams.set("ap", "");
|
|
141
162
|
|
|
@@ -155,27 +176,11 @@ const FormatNFTMetadata = function(nft) {
|
|
|
155
176
|
|
|
156
177
|
exports.FormatNFTMetadata = FormatNFTMetadata;
|
|
157
178
|
|
|
158
|
-
exports.FormatNFT = function (item) {
|
|
159
|
-
return FormatNFTMetadata(FormatNFTDetails(item));
|
|
179
|
+
exports.FormatNFT = function (walletClient, item) {
|
|
180
|
+
return FormatNFTMetadata(walletClient, FormatNFTDetails(item));
|
|
160
181
|
};
|
|
161
182
|
|
|
162
183
|
|
|
163
|
-
exports.LinkTargetHash = function(link) {
|
|
164
|
-
if(!link) { return; }
|
|
165
|
-
|
|
166
|
-
if(link["."] && link["."].source) {
|
|
167
|
-
return link["."].source;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if(link["/"] && link["/"].startsWith("/qfab/")) {
|
|
171
|
-
return link["/"].split("/").find(segment => segment.startsWith("hq__"));
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if(link["."] && link["."].container) {
|
|
175
|
-
return link["."].container;
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
|
|
179
184
|
// https://stackoverflow.com/questions/4068373/center-a-popup-window-on-screen
|
|
180
185
|
const Popup = ({url, title, w, h}) => {
|
|
181
186
|
// Fixes dual-screen position
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const {ElvClient} = require("../ElvClient");
|
|
2
2
|
const Configuration = require("./Configuration");
|
|
3
3
|
const {LinkTargetHash, FormatNFT, ActionPopup} = require("./Utils");
|
|
4
|
+
const HTTPClient = require("../HttpClient");
|
|
4
5
|
const UrlJoin = require("url-join");
|
|
5
6
|
const Utils = require("../Utils");
|
|
6
7
|
const Ethers = require("ethers");
|
|
@@ -15,7 +16,9 @@ const embedded = inBrowser && window.top !== window.self;
|
|
|
15
16
|
* See the Modules section on the sidebar for all client methods unrelated to login and authorization
|
|
16
17
|
*/
|
|
17
18
|
class ElvWalletClient {
|
|
18
|
-
constructor({client, network, mode, marketplaceInfo, storeAuthToken}) {
|
|
19
|
+
constructor({appId, client, network, mode, marketplaceInfo, previewMarketplaceHash, storeAuthToken}) {
|
|
20
|
+
this.appId = appId;
|
|
21
|
+
|
|
19
22
|
this.client = client;
|
|
20
23
|
this.loggedIn = false;
|
|
21
24
|
|
|
@@ -28,11 +31,16 @@ class ElvWalletClient {
|
|
|
28
31
|
this.storeAuthToken = storeAuthToken;
|
|
29
32
|
|
|
30
33
|
this.selectedMarketplaceInfo = marketplaceInfo;
|
|
34
|
+
this.previewMarketplaceId = previewMarketplaceHash ? Utils.DecodeVersionHash(previewMarketplaceHash).objectId : undefined;
|
|
35
|
+
this.previewMarketplaceHash = previewMarketplaceHash;
|
|
31
36
|
|
|
32
37
|
this.availableMarketplaces = {};
|
|
33
38
|
this.availableMarketplacesById = {};
|
|
34
39
|
this.marketplaceHashes = {};
|
|
35
40
|
|
|
41
|
+
this.stateStoreUrls = Configuration[network].stateStoreUrls;
|
|
42
|
+
this.stateStoreClient = new HTTPClient({uris: this.stateStoreUrls});
|
|
43
|
+
|
|
36
44
|
// Caches
|
|
37
45
|
this.cachedMarketplaces = {};
|
|
38
46
|
this.cachedCSS = {};
|
|
@@ -60,8 +68,10 @@ class ElvWalletClient {
|
|
|
60
68
|
*
|
|
61
69
|
* Specify tenantSlug and marketplaceSlug to automatically associate this tenant with a particular marketplace.
|
|
62
70
|
*
|
|
71
|
+
*
|
|
63
72
|
* @methodGroup Initialization
|
|
64
73
|
* @namedParams
|
|
74
|
+
* @param {string} appId - A string identifying your app. This is used for namespacing user profile data.
|
|
65
75
|
* @param {string} network=main - Name of the Fabric network to use (`main`, `demo`)
|
|
66
76
|
* @param {string} mode=production - Environment to use (`production`, `staging`)
|
|
67
77
|
* @param {Object=} marketplaceParams - Marketplace parameters
|
|
@@ -70,9 +80,11 @@ class ElvWalletClient {
|
|
|
70
80
|
* @returns {Promise<ElvWalletClient>}
|
|
71
81
|
*/
|
|
72
82
|
static async Initialize({
|
|
83
|
+
appId="general",
|
|
73
84
|
network="main",
|
|
74
85
|
mode="production",
|
|
75
86
|
marketplaceParams,
|
|
87
|
+
previewMarketplaceId,
|
|
76
88
|
storeAuthToken=true
|
|
77
89
|
}) {
|
|
78
90
|
let { tenantSlug, marketplaceSlug, marketplaceId, marketplaceHash } = (marketplaceParams || {});
|
|
@@ -85,7 +97,13 @@ class ElvWalletClient {
|
|
|
85
97
|
|
|
86
98
|
const client = await ElvClient.FromNetworkName({networkName: network, assumeV3: true});
|
|
87
99
|
|
|
100
|
+
let previewMarketplaceHash = previewMarketplaceId;
|
|
101
|
+
if(previewMarketplaceHash && !previewMarketplaceHash.startsWith("hq__")) {
|
|
102
|
+
previewMarketplaceHash = await client.LatestVersionHash({objectId: previewMarketplaceId});
|
|
103
|
+
}
|
|
104
|
+
|
|
88
105
|
const walletClient = new ElvWalletClient({
|
|
106
|
+
appId,
|
|
89
107
|
client,
|
|
90
108
|
network,
|
|
91
109
|
mode,
|
|
@@ -95,6 +113,7 @@ class ElvWalletClient {
|
|
|
95
113
|
marketplaceId: marketplaceHash ? client.utils.DecodeVersionHash(marketplaceHash).objectId : marketplaceId,
|
|
96
114
|
marketplaceHash
|
|
97
115
|
},
|
|
116
|
+
previewMarketplaceHash,
|
|
98
117
|
storeAuthToken
|
|
99
118
|
});
|
|
100
119
|
|
|
@@ -217,6 +236,9 @@ class ElvWalletClient {
|
|
|
217
236
|
/**
|
|
218
237
|
* Direct the user to the Eluvio Media Wallet login page.
|
|
219
238
|
*
|
|
239
|
+
* For redirect login, the authorization token will be included in the URL parameters of the callbackUrl. Simply re-initialize the wallet client and it will authorize with this token,
|
|
240
|
+
* or you can retrieve the parameter (`elvToken`) yourself and use it in the <a href="#Authenticate">Authenticate</a> method.
|
|
241
|
+
*
|
|
220
242
|
* <b>NOTE:</b> The domain of the opening window (popup flow) or domain of the `callbackUrl` (redirect flow) MUST be allowed in the metadata of the specified marketplace.
|
|
221
243
|
*
|
|
222
244
|
* @methodGroup Login
|
|
@@ -552,14 +574,13 @@ class ElvWalletClient {
|
|
|
552
574
|
|
|
553
575
|
|
|
554
576
|
|
|
555
|
-
// If marketplace slug is specified, load only that marketplace. Otherwise load all
|
|
556
577
|
async LoadAvailableMarketplaces(forceReload=false) {
|
|
557
578
|
if(!forceReload && Object.keys(this.availableMarketplaces) > 0) {
|
|
558
579
|
return;
|
|
559
580
|
}
|
|
560
581
|
|
|
561
582
|
const mainSiteHash = await this.client.LatestVersionHash({objectId: this.mainSiteId});
|
|
562
|
-
|
|
583
|
+
let metadata = await this.client.ContentObjectMetadata({
|
|
563
584
|
versionHash: mainSiteHash,
|
|
564
585
|
metadataSubtree: "public/asset_metadata/tenants",
|
|
565
586
|
resolveLinks: true,
|
|
@@ -581,13 +602,74 @@ class ElvWalletClient {
|
|
|
581
602
|
]
|
|
582
603
|
});
|
|
583
604
|
|
|
605
|
+
// If preview marketplace is specified, load it appropriately
|
|
606
|
+
if(this.previewMarketplaceId) {
|
|
607
|
+
let previewTenantSlug = "PREVIEW";
|
|
608
|
+
let previewMarketplaceSlug, previewMarketplaceMetadata;
|
|
609
|
+
Object.keys(metadata || {}).forEach(tenantSlug =>
|
|
610
|
+
Object.keys(metadata[tenantSlug].marketplaces || {}).forEach(marketplaceSlug => {
|
|
611
|
+
const versionHash = metadata[tenantSlug].marketplaces[marketplaceSlug]["."].source;
|
|
612
|
+
const objectId = this.utils.DecodeVersionHash(versionHash).objectId;
|
|
613
|
+
|
|
614
|
+
if(objectId === this.previewMarketplaceId) {
|
|
615
|
+
// Marketplace exists in site meta
|
|
616
|
+
previewTenantSlug = tenantSlug;
|
|
617
|
+
previewMarketplaceSlug = marketplaceSlug;
|
|
618
|
+
|
|
619
|
+
// Deployed marketplace is same as preview marketplace
|
|
620
|
+
if(versionHash === this.previewMarketplaceHash) {
|
|
621
|
+
previewMarketplaceMetadata = metadata[tenantSlug].marketplaces[marketplaceSlug];
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
})
|
|
625
|
+
);
|
|
626
|
+
|
|
627
|
+
// Marketplace not present in branch, or preview version is different - Load metadata directly
|
|
628
|
+
if(!previewMarketplaceMetadata) {
|
|
629
|
+
previewMarketplaceMetadata = await this.client.ContentObjectMetadata({
|
|
630
|
+
versionHash: this.previewMarketplaceHash,
|
|
631
|
+
metadataSubtree: "public/asset_metadata",
|
|
632
|
+
produceLinkUrls: true,
|
|
633
|
+
authorizationToken: this.publicStaticToken,
|
|
634
|
+
noAuth: true,
|
|
635
|
+
select: [
|
|
636
|
+
"slug",
|
|
637
|
+
"info/tenant_id",
|
|
638
|
+
"info/tenant_name",
|
|
639
|
+
"info/branding",
|
|
640
|
+
],
|
|
641
|
+
remove: [
|
|
642
|
+
"info/branding/custom_css"
|
|
643
|
+
]
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
if(!previewMarketplaceSlug) {
|
|
647
|
+
previewMarketplaceSlug = previewMarketplaceMetadata.slug;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
previewMarketplaceMetadata["."] = {
|
|
652
|
+
source: this.previewMarketplaceHash
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
previewMarketplaceMetadata.info["."] = {
|
|
656
|
+
source: this.previewMarketplaceHash
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
previewMarketplaceMetadata.info.branding.preview = true;
|
|
660
|
+
previewMarketplaceMetadata.info.branding.show = true;
|
|
661
|
+
|
|
662
|
+
metadata[previewTenantSlug] = metadata[previewTenantSlug] || {};
|
|
663
|
+
metadata[previewTenantSlug].marketplaces = metadata[previewTenantSlug].marketplaces || {};
|
|
664
|
+
metadata[previewTenantSlug].marketplaces[previewMarketplaceSlug] = previewMarketplaceMetadata;
|
|
665
|
+
}
|
|
666
|
+
|
|
584
667
|
let availableMarketplaces = { ...(this.availableMarketplaces || {}) };
|
|
585
668
|
let availableMarketplacesById = { ...(this.availableMarketplacesById || {}) };
|
|
586
669
|
Object.keys(metadata || {}).forEach(tenantSlug => {
|
|
587
670
|
try {
|
|
588
|
-
availableMarketplaces[tenantSlug] =
|
|
589
|
-
versionHash: metadata[tenantSlug]["."].source
|
|
590
|
-
};
|
|
671
|
+
availableMarketplaces[tenantSlug] = metadata[tenantSlug]["."] ?
|
|
672
|
+
{ versionHash: metadata[tenantSlug]["."].source } : { };
|
|
591
673
|
|
|
592
674
|
Object.keys(metadata[tenantSlug].marketplaces || {}).forEach(marketplaceSlug => {
|
|
593
675
|
try {
|
|
@@ -629,11 +711,17 @@ class ElvWalletClient {
|
|
|
629
711
|
}
|
|
630
712
|
|
|
631
713
|
// Get the hash of the currently linked marketplace
|
|
632
|
-
async LatestMarketplaceHash({
|
|
714
|
+
async LatestMarketplaceHash({marketplaceParams}) {
|
|
715
|
+
const marketplaceInfo = await this.MarketplaceInfo({marketplaceParams});
|
|
716
|
+
|
|
717
|
+
if(this.previewMarketplaceId && this.previewMarketplaceId === marketplaceInfo.marketplaceId) {
|
|
718
|
+
return this.availableMarketplaces[marketplaceInfo.tenantSlug][marketplaceInfo.marketplaceSlug]["."].source;
|
|
719
|
+
}
|
|
720
|
+
|
|
633
721
|
const mainSiteHash = await this.client.LatestVersionHash({objectId: this.mainSiteId});
|
|
634
722
|
const marketplaceLink = await this.client.ContentObjectMetadata({
|
|
635
723
|
versionHash: mainSiteHash,
|
|
636
|
-
metadataSubtree: UrlJoin("/public", "asset_metadata", "tenants", tenantSlug, "marketplaces", marketplaceSlug),
|
|
724
|
+
metadataSubtree: UrlJoin("/public", "asset_metadata", "tenants", marketplaceInfo.tenantSlug, "marketplaces", marketplaceInfo.marketplaceSlug),
|
|
637
725
|
resolveLinks: false
|
|
638
726
|
});
|
|
639
727
|
|
|
@@ -644,7 +732,7 @@ class ElvWalletClient {
|
|
|
644
732
|
const marketplaceInfo = this.MarketplaceInfo({marketplaceParams});
|
|
645
733
|
|
|
646
734
|
const marketplaceId = marketplaceInfo.marketplaceId;
|
|
647
|
-
const marketplaceHash = await this.LatestMarketplaceHash({
|
|
735
|
+
const marketplaceHash = await this.LatestMarketplaceHash({marketplaceParams});
|
|
648
736
|
|
|
649
737
|
if(this.cachedMarketplaces[marketplaceId] && this.cachedMarketplaces[marketplaceId].versionHash !== marketplaceHash) {
|
|
650
738
|
delete this.cachedMarketplaces[marketplaceId];
|
|
@@ -698,6 +786,10 @@ class ElvWalletClient {
|
|
|
698
786
|
marketplace.marketplaceId = marketplaceId;
|
|
699
787
|
marketplace.versionHash = marketplaceHash;
|
|
700
788
|
|
|
789
|
+
if(this.previewMarketplaceId && marketplaceId === this.previewMarketplaceId) {
|
|
790
|
+
marketplace.branding.preview = true;
|
|
791
|
+
}
|
|
792
|
+
|
|
701
793
|
// Generate embed URLs for pack opening animations
|
|
702
794
|
["purchase_animation", "purchase_animation__mobile", "reveal_animation", "reveal_animation_mobile"].forEach(key => {
|
|
703
795
|
try {
|
|
@@ -744,20 +836,29 @@ class ElvWalletClient {
|
|
|
744
836
|
priceRange,
|
|
745
837
|
tokenIdRange,
|
|
746
838
|
capLimit,
|
|
839
|
+
userAddress,
|
|
747
840
|
sellerAddress,
|
|
748
841
|
lastNDays=-1,
|
|
842
|
+
includeCheckoutLocked=false,
|
|
749
843
|
start=0,
|
|
750
844
|
limit=50
|
|
751
845
|
}={}) {
|
|
752
846
|
collectionIndexes = (collectionIndexes || []).map(i => parseInt(i));
|
|
753
847
|
|
|
754
848
|
let params = {
|
|
755
|
-
sort_by: sortBy,
|
|
756
|
-
sort_descending: sortDesc,
|
|
757
849
|
start,
|
|
758
|
-
limit
|
|
850
|
+
limit,
|
|
851
|
+
sort_descending: sortDesc
|
|
759
852
|
};
|
|
760
853
|
|
|
854
|
+
if(mode !== "leaderboard") {
|
|
855
|
+
params.sort_by = sortBy;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
if(mode.includes("listings") && includeCheckoutLocked) {
|
|
859
|
+
params.checkout = true;
|
|
860
|
+
}
|
|
861
|
+
|
|
761
862
|
let marketplaceInfo, marketplace;
|
|
762
863
|
if(marketplaceParams) {
|
|
763
864
|
marketplaceInfo = await this.MarketplaceInfo({marketplaceParams});
|
|
@@ -772,6 +873,8 @@ class ElvWalletClient {
|
|
|
772
873
|
|
|
773
874
|
if(sellerAddress) {
|
|
774
875
|
filters.push(`seller:eq:${this.client.utils.FormatAddress(sellerAddress)}`);
|
|
876
|
+
} else if(userAddress && mode !== "owned") {
|
|
877
|
+
filters.push(`addr:eq:${this.client.utils.FormatAddress(userAddress)}`);
|
|
775
878
|
}
|
|
776
879
|
|
|
777
880
|
if(marketplace && collectionIndexes.length >= 0) {
|
|
@@ -798,7 +901,7 @@ class ElvWalletClient {
|
|
|
798
901
|
}
|
|
799
902
|
});
|
|
800
903
|
});
|
|
801
|
-
} else if(
|
|
904
|
+
} else if(marketplaceInfo || tenantId) {
|
|
802
905
|
filters.push(`tenant:eq:${marketplaceInfo ? marketplaceInfo.tenantId : tenantId}`);
|
|
803
906
|
}
|
|
804
907
|
|
|
@@ -816,8 +919,7 @@ class ElvWalletClient {
|
|
|
816
919
|
if(mode.includes("listing")) {
|
|
817
920
|
filters.push(`nft/display_name:eq:${filter}`);
|
|
818
921
|
} else if(mode === "owned") {
|
|
819
|
-
filters.push(`meta
|
|
820
|
-
params.exact = false;
|
|
922
|
+
filters.push(`meta/display_name:eq:${filter}`);
|
|
821
923
|
} else {
|
|
822
924
|
filters.push(`name:eq:${filter}`);
|
|
823
925
|
}
|
|
@@ -880,12 +982,7 @@ class ElvWalletClient {
|
|
|
880
982
|
let path;
|
|
881
983
|
switch(mode) {
|
|
882
984
|
case "owned":
|
|
883
|
-
path = UrlJoin("as", "wlt",
|
|
884
|
-
|
|
885
|
-
if(marketplaceInfo) {
|
|
886
|
-
path = UrlJoin("as", "wlt", "nfts", marketplaceInfo.tenantId);
|
|
887
|
-
}
|
|
888
|
-
|
|
985
|
+
path = UrlJoin("as", "wlt", userAddress || this.UserAddress());
|
|
889
986
|
break;
|
|
890
987
|
|
|
891
988
|
case "listings":
|
|
@@ -912,6 +1009,10 @@ class ElvWalletClient {
|
|
|
912
1009
|
path = UrlJoin("as", "mkt", "stats", "sold");
|
|
913
1010
|
filters.push("seller:co:0x");
|
|
914
1011
|
break;
|
|
1012
|
+
|
|
1013
|
+
case "leaderboard":
|
|
1014
|
+
path = UrlJoin("as", "wlt", "leaders");
|
|
1015
|
+
break;
|
|
915
1016
|
}
|
|
916
1017
|
|
|
917
1018
|
if(filters.length > 0) {
|
|
@@ -932,10 +1033,7 @@ class ElvWalletClient {
|
|
|
932
1033
|
await this.client.authClient.MakeAuthServiceRequest({
|
|
933
1034
|
path,
|
|
934
1035
|
method: "GET",
|
|
935
|
-
queryParams: params
|
|
936
|
-
headers: mode === "owned" ?
|
|
937
|
-
{ Authorization: `Bearer ${this.AuthToken()}` } :
|
|
938
|
-
{}
|
|
1036
|
+
queryParams: params
|
|
939
1037
|
})
|
|
940
1038
|
) || [];
|
|
941
1039
|
|
|
@@ -946,7 +1044,7 @@ class ElvWalletClient {
|
|
|
946
1044
|
total: paging.total,
|
|
947
1045
|
more: paging.total > start + limit
|
|
948
1046
|
},
|
|
949
|
-
results: (contents || []).map(item => ["owned", "listings"].includes(mode) ? FormatNFT(item) : item)
|
|
1047
|
+
results: (contents || []).map(item => ["owned", "listings"].includes(mode) ? FormatNFT(this, item) : item)
|
|
950
1048
|
};
|
|
951
1049
|
} catch(error) {
|
|
952
1050
|
if(error.status && error.status.toString() === "404") {
|
|
@@ -1029,5 +1127,6 @@ class ElvWalletClient {
|
|
|
1029
1127
|
}
|
|
1030
1128
|
|
|
1031
1129
|
Object.assign(ElvWalletClient.prototype, require("./ClientMethods"));
|
|
1130
|
+
Object.assign(ElvWalletClient.prototype, require("./Profile"));
|
|
1032
1131
|
|
|
1033
1132
|
exports.ElvWalletClient = ElvWalletClient;
|