@highlightxyz/cli 0.1.0 → 0.3.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.
- package/README.md +72 -81
- package/lib/index.js +626 -74
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1,30 +1,55 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Highlight CLI
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Use `hl` to manage Highlight from a terminal, script, CI job, or agent. It
|
|
4
|
+
covers collections, deployment, sales, gates, media, tokens, contracts, and
|
|
5
|
+
chain configuration.
|
|
6
|
+
|
|
7
|
+
The CLI is built on `@highlightxyz/sdk`. It calls the same API and follows the
|
|
8
|
+
same validation rules as the SDK and REST API.
|
|
9
|
+
|
|
10
|
+
[Read the CLI documentation](https://docs.highlight.xyz/cli/setup/).
|
|
6
11
|
|
|
7
12
|
## Install
|
|
8
13
|
|
|
14
|
+
```sh
|
|
15
|
+
npm install --global @highlightxyz/cli
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or use Bun:
|
|
19
|
+
|
|
9
20
|
```sh
|
|
10
21
|
bun add --global @highlightxyz/cli
|
|
11
22
|
```
|
|
12
23
|
|
|
13
|
-
Node.js 20 or later
|
|
24
|
+
The CLI requires Node.js 20 or later.
|
|
25
|
+
|
|
26
|
+
Verify the installation:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
hl --version
|
|
30
|
+
hl --help
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
You can run public commands before signing in:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
hl chains list --testnet
|
|
37
|
+
```
|
|
14
38
|
|
|
15
39
|
## Authenticate
|
|
16
40
|
|
|
17
|
-
Create an API key in Highlight, then
|
|
41
|
+
Create an API key in Highlight, then save and verify it:
|
|
18
42
|
|
|
19
43
|
```sh
|
|
20
44
|
hl auth login
|
|
45
|
+
hl auth status
|
|
21
46
|
```
|
|
22
47
|
|
|
23
|
-
For CI and agents,
|
|
48
|
+
For CI and agents, set the key in the process environment:
|
|
24
49
|
|
|
25
50
|
```sh
|
|
26
51
|
export HIGHLIGHT_API_KEY="hl_live_..."
|
|
27
|
-
hl auth status
|
|
52
|
+
hl auth status --json
|
|
28
53
|
```
|
|
29
54
|
|
|
30
55
|
Named profiles and custom API URLs are supported:
|
|
@@ -34,11 +59,11 @@ hl auth login --profile staging --api-url http://localhost:8787
|
|
|
34
59
|
hl collections list --profile staging
|
|
35
60
|
```
|
|
36
61
|
|
|
37
|
-
|
|
38
|
-
`
|
|
39
|
-
saved configuration.
|
|
62
|
+
On macOS and Linux, saved keys live in
|
|
63
|
+
`~/.config/highlight/config.json` with mode `0600`. `HIGHLIGHT_API_KEY`,
|
|
64
|
+
`HIGHLIGHT_API_URL`, and `HIGHLIGHT_CONFIG_DIR` override saved configuration.
|
|
40
65
|
|
|
41
|
-
##
|
|
66
|
+
## Core commands
|
|
42
67
|
|
|
43
68
|
```sh
|
|
44
69
|
hl collections list
|
|
@@ -47,75 +72,23 @@ hl collections create --input collection.json
|
|
|
47
72
|
hl collections deploy <highlight-id> --wait
|
|
48
73
|
hl collections deploy-status <highlight-id>
|
|
49
74
|
hl collections deploy-cancel <highlight-id>
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Creation input uses the SDK's `collection.create` shape:
|
|
53
|
-
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"name": "My Drop",
|
|
57
|
-
"description": "Created with the Highlight CLI",
|
|
58
|
-
"type": "OpenEdition",
|
|
59
|
-
"logoMediaId": "00000000-0000-0000-0000-000000000000",
|
|
60
|
-
"image": "https://assets.example/art.png",
|
|
61
|
-
"contract": {
|
|
62
|
-
"chainId": 84532,
|
|
63
|
-
"name": "My Drop",
|
|
64
|
-
"symbol": "DROP",
|
|
65
|
-
"standard": "ERC721"
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Use `--input -` to read JSON from stdin.
|
|
71
|
-
|
|
72
|
-
## Sales
|
|
73
75
|
|
|
74
|
-
```sh
|
|
75
76
|
hl sales list <highlight-id>
|
|
76
77
|
hl sales create <highlight-id> --input sale.json
|
|
77
78
|
hl sales update <highlight-id> <sale-id> --input sale-update.json
|
|
78
79
|
hl sales delete <highlight-id> <sale-id>
|
|
79
|
-
```
|
|
80
80
|
|
|
81
|
-
Sale input uses the SDK's `collection.addSale` body shape:
|
|
82
|
-
|
|
83
|
-
```json
|
|
84
|
-
{
|
|
85
|
-
"type": "FIXED_PRICE",
|
|
86
|
-
"accessMode": "PUBLIC",
|
|
87
|
-
"startAt": "2026-01-01T00:00:00.000Z",
|
|
88
|
-
"price": "0.01",
|
|
89
|
-
"currency": "ETH",
|
|
90
|
-
"maxPerTransaction": 5,
|
|
91
|
-
"maxPerWallet": 10,
|
|
92
|
-
"maxTotal": 100,
|
|
93
|
-
"paymentRecipient": "0x0000000000000000000000000000000000000001"
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
The API enforces the collection functionality matrices. Unsupported
|
|
98
|
-
combinations, such as gated ranked auctions, return the canonical domain error.
|
|
99
|
-
Live public sale changes can return a transaction payload that requires a
|
|
100
|
-
wallet signature.
|
|
101
|
-
|
|
102
|
-
## Gates
|
|
103
|
-
|
|
104
|
-
```sh
|
|
105
81
|
hl gates list
|
|
106
82
|
hl gates get <gate-id>
|
|
107
83
|
hl gates create --input gate.json
|
|
108
84
|
hl gates update <gate-id> --input gate-update.json
|
|
109
85
|
hl gates delete <gate-id>
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Gate JSON uses the SDK `gate.create` or `gate.update` body shape and supports
|
|
113
|
-
allowlists, token ownership, specific tokens, token attributes, currency
|
|
114
|
-
balances, and Farcaster follows.
|
|
115
86
|
|
|
116
|
-
|
|
87
|
+
hl media upload ./art.png
|
|
88
|
+
hl media upload ./generative-code.zip --kind directory
|
|
89
|
+
hl media get <media-id>
|
|
90
|
+
hl media publish <media-id>
|
|
117
91
|
|
|
118
|
-
```sh
|
|
119
92
|
hl contracts list
|
|
120
93
|
hl contracts get <contract-id>
|
|
121
94
|
|
|
@@ -129,30 +102,48 @@ hl chains list --testnet
|
|
|
129
102
|
hl chains system-contract 84532 MintManager
|
|
130
103
|
```
|
|
131
104
|
|
|
132
|
-
|
|
133
|
-
Contract queries and token reveal redrives require authentication.
|
|
134
|
-
|
|
135
|
-
## Media
|
|
105
|
+
Run group help for every option:
|
|
136
106
|
|
|
137
107
|
```sh
|
|
138
|
-
hl
|
|
139
|
-
hl
|
|
140
|
-
hl media
|
|
141
|
-
hl media publish <media-id>
|
|
108
|
+
hl collections --help
|
|
109
|
+
hl sales --help
|
|
110
|
+
hl media --help
|
|
142
111
|
```
|
|
143
112
|
|
|
144
|
-
|
|
113
|
+
Collection, sale, and gate writes accept JSON with `--input <file>`. Use
|
|
114
|
+
`--input -` to read it from stdin.
|
|
115
|
+
|
|
116
|
+
## Current boundaries
|
|
117
|
+
|
|
118
|
+
`hl collections create` creates the base draft. Version `0.1.0` does not
|
|
119
|
+
configure edition, series, or generative details, so complete those fields in
|
|
120
|
+
the dashboard, SDK, or REST API before deployment.
|
|
121
|
+
|
|
122
|
+
The CLI does not read or store wallet keys. When deployment or a live sale
|
|
123
|
+
change needs an on-chain transaction, it prints the payload for a wallet to
|
|
124
|
+
sign. It does not broadcast that transaction or submit its hash for tracking.
|
|
125
|
+
|
|
126
|
+
Auction configuration is available through the generic sale commands. Bids,
|
|
127
|
+
claims, standings, settlement, and earnings actions remain SDK or REST
|
|
128
|
+
operations.
|
|
145
129
|
|
|
146
130
|
## Automation
|
|
147
131
|
|
|
148
|
-
Pass `--json` anywhere in
|
|
149
|
-
output:
|
|
132
|
+
Pass `--json` anywhere in a command for machine-readable output:
|
|
150
133
|
|
|
151
134
|
```sh
|
|
152
135
|
hl collections list --json
|
|
153
136
|
hl media upload ./art.png --json
|
|
154
137
|
```
|
|
155
138
|
|
|
156
|
-
|
|
139
|
+
Successful JSON goes to stdout. Errors go to stderr. Commands return:
|
|
140
|
+
|
|
141
|
+
- `0` on success
|
|
142
|
+
- `1` for API, authentication, filesystem, timeout, or processing failures
|
|
143
|
+
- `2` for invalid commands, options, arguments, or JSON input
|
|
157
144
|
|
|
158
|
-
|
|
145
|
+
Pin the package version in production automation:
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
npm install --global @highlightxyz/cli@0.1.0
|
|
149
|
+
```
|
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// package.json
|
|
3
3
|
var package_default = {
|
|
4
4
|
name: "@highlightxyz/cli",
|
|
5
|
-
version: "0.
|
|
5
|
+
version: "0.3.0",
|
|
6
6
|
description: "Official command-line interface for the Highlight API",
|
|
7
7
|
keywords: [
|
|
8
8
|
"cli",
|
|
@@ -18,13 +18,16 @@ var package_default = {
|
|
|
18
18
|
url: "https://github.com/highlight-xyz/highlight-app.git",
|
|
19
19
|
directory: "packages/cli"
|
|
20
20
|
},
|
|
21
|
+
bin: {
|
|
22
|
+
hl: "./lib/index.js"
|
|
23
|
+
},
|
|
21
24
|
files: [
|
|
22
25
|
"lib",
|
|
23
26
|
"README.md"
|
|
24
27
|
],
|
|
25
28
|
type: "module",
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
publishConfig: {
|
|
30
|
+
access: "public"
|
|
28
31
|
},
|
|
29
32
|
scripts: {
|
|
30
33
|
build: "bun build ./src/index.ts --outfile ./lib/index.js --target node --format esm",
|
|
@@ -45,9 +48,6 @@ var package_default = {
|
|
|
45
48
|
},
|
|
46
49
|
engines: {
|
|
47
50
|
node: ">=20"
|
|
48
|
-
},
|
|
49
|
-
publishConfig: {
|
|
50
|
-
access: "public"
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
|
|
@@ -209,6 +209,15 @@ var SaleAccessMode;
|
|
|
209
209
|
SaleAccessMode2["Public"] = "PUBLIC";
|
|
210
210
|
SaleAccessMode2["Gated"] = "GATED";
|
|
211
211
|
})(SaleAccessMode ||= {});
|
|
212
|
+
var MediaPurpose;
|
|
213
|
+
((MediaPurpose2) => {
|
|
214
|
+
MediaPurpose2["CollectionLogo"] = "CollectionLogo";
|
|
215
|
+
MediaPurpose2["EditionImage"] = "EditionImage";
|
|
216
|
+
MediaPurpose2["EditionAnimation"] = "EditionAnimation";
|
|
217
|
+
MediaPurpose2["SeriesAssets"] = "SeriesAssets";
|
|
218
|
+
MediaPurpose2["GenerativeCode"] = "GenerativeCode";
|
|
219
|
+
MediaPurpose2["UserAvatar"] = "UserAvatar";
|
|
220
|
+
})(MediaPurpose ||= {});
|
|
212
221
|
var GateMatchMode;
|
|
213
222
|
((GateMatchMode2) => {
|
|
214
223
|
GateMatchMode2["All"] = "ALL";
|
|
@@ -1150,8 +1159,6 @@ class Collection extends HeyApiClient {
|
|
|
1150
1159
|
{ in: "body", key: "description" },
|
|
1151
1160
|
{ in: "body", key: "contractId" },
|
|
1152
1161
|
{ in: "body", key: "contract" },
|
|
1153
|
-
{ in: "body", key: "logoMediaId" },
|
|
1154
|
-
{ in: "body", key: "image" },
|
|
1155
1162
|
{ in: "body", key: "type" },
|
|
1156
1163
|
{ in: "body", key: "royalty" },
|
|
1157
1164
|
{ in: "body", key: "tokenManager" }
|
|
@@ -1223,14 +1230,58 @@ class Collection extends HeyApiClient {
|
|
|
1223
1230
|
...params
|
|
1224
1231
|
});
|
|
1225
1232
|
}
|
|
1226
|
-
|
|
1233
|
+
archiveBaseUri(parameters, options) {
|
|
1227
1234
|
const params = buildClientParams([parameters], [{ args: [{ in: "path", key: "highlightId" }] }]);
|
|
1228
1235
|
return (options?.client ?? this.client).post({
|
|
1229
|
-
url: "/collection/{highlightId}/
|
|
1236
|
+
url: "/collection/{highlightId}/archive-base-uri",
|
|
1230
1237
|
...options,
|
|
1231
1238
|
...params
|
|
1232
1239
|
});
|
|
1233
1240
|
}
|
|
1241
|
+
createMediaUploadSession(parameters, options) {
|
|
1242
|
+
const params = buildClientParams([parameters], [
|
|
1243
|
+
{
|
|
1244
|
+
args: [
|
|
1245
|
+
{ in: "path", key: "highlightId" },
|
|
1246
|
+
{ in: "body", key: "purpose" },
|
|
1247
|
+
{ in: "body", key: "fileName" },
|
|
1248
|
+
{ in: "body", key: "mimeType" },
|
|
1249
|
+
{ in: "body", key: "fileSize" },
|
|
1250
|
+
{ in: "body", key: "contentHash" }
|
|
1251
|
+
]
|
|
1252
|
+
}
|
|
1253
|
+
]);
|
|
1254
|
+
return (options?.client ?? this.client).post({
|
|
1255
|
+
url: "/collection/{highlightId}/media/upload-session",
|
|
1256
|
+
...options,
|
|
1257
|
+
...params,
|
|
1258
|
+
headers: {
|
|
1259
|
+
"Content-Type": "application/json",
|
|
1260
|
+
...options?.headers,
|
|
1261
|
+
...params.headers
|
|
1262
|
+
}
|
|
1263
|
+
});
|
|
1264
|
+
}
|
|
1265
|
+
updateMetadata(parameters, options) {
|
|
1266
|
+
const params = buildClientParams([parameters], [
|
|
1267
|
+
{
|
|
1268
|
+
args: [
|
|
1269
|
+
{ in: "path", key: "highlightId" },
|
|
1270
|
+
{ key: "collectionUpdateMetadataInput", map: "body" }
|
|
1271
|
+
]
|
|
1272
|
+
}
|
|
1273
|
+
]);
|
|
1274
|
+
return (options?.client ?? this.client).patch({
|
|
1275
|
+
url: "/collection/{highlightId}/metadata",
|
|
1276
|
+
...options,
|
|
1277
|
+
...params,
|
|
1278
|
+
headers: {
|
|
1279
|
+
"Content-Type": "application/json",
|
|
1280
|
+
...options?.headers,
|
|
1281
|
+
...params.headers
|
|
1282
|
+
}
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1234
1285
|
updateGenerativeDetails(parameters, options) {
|
|
1235
1286
|
const params = buildClientParams([parameters], [
|
|
1236
1287
|
{
|
|
@@ -1316,7 +1367,6 @@ class Collection extends HeyApiClient {
|
|
|
1316
1367
|
{ in: "body", key: "paymentRecipient" },
|
|
1317
1368
|
{ in: "body", key: "accessMode" },
|
|
1318
1369
|
{ in: "body", key: "gateId" },
|
|
1319
|
-
{ in: "body", key: "gasSponsored" },
|
|
1320
1370
|
{ in: "body", key: "mechanicId" },
|
|
1321
1371
|
{ in: "body", key: "typeConfig" },
|
|
1322
1372
|
{ in: "body", key: "collectorMessage" },
|
|
@@ -1553,6 +1603,41 @@ class Collection extends HeyApiClient {
|
|
|
1553
1603
|
...params
|
|
1554
1604
|
});
|
|
1555
1605
|
}
|
|
1606
|
+
dutchAuctionStanding(parameters, options) {
|
|
1607
|
+
const params = buildClientParams([parameters], [
|
|
1608
|
+
{
|
|
1609
|
+
args: [
|
|
1610
|
+
{ in: "path", key: "highlightId" },
|
|
1611
|
+
{ in: "path", key: "saleId" }
|
|
1612
|
+
]
|
|
1613
|
+
}
|
|
1614
|
+
]);
|
|
1615
|
+
return (options?.client ?? this.client).get({
|
|
1616
|
+
url: "/collection/{highlightId}/sales/{saleId}/dutch",
|
|
1617
|
+
...options,
|
|
1618
|
+
...params
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
claimDutchRebate(parameters, options) {
|
|
1622
|
+
const params = buildClientParams([parameters], [
|
|
1623
|
+
{
|
|
1624
|
+
args: [
|
|
1625
|
+
{ in: "path", key: "highlightId" },
|
|
1626
|
+
{ in: "body", key: "saleId" }
|
|
1627
|
+
]
|
|
1628
|
+
}
|
|
1629
|
+
]);
|
|
1630
|
+
return (options?.client ?? this.client).post({
|
|
1631
|
+
url: "/collection/{highlightId}/sales/dutch/rebate",
|
|
1632
|
+
...options,
|
|
1633
|
+
...params,
|
|
1634
|
+
headers: {
|
|
1635
|
+
"Content-Type": "application/json",
|
|
1636
|
+
...options?.headers,
|
|
1637
|
+
...params.headers
|
|
1638
|
+
}
|
|
1639
|
+
});
|
|
1640
|
+
}
|
|
1556
1641
|
deploy(parameters, options) {
|
|
1557
1642
|
const params = buildClientParams([parameters], [{ args: [{ in: "path", key: "highlightId" }] }]);
|
|
1558
1643
|
return (options?.client ?? this.client).post({
|
|
@@ -1656,6 +1741,12 @@ class Config extends HeyApiClient {
|
|
|
1656
1741
|
...options
|
|
1657
1742
|
});
|
|
1658
1743
|
}
|
|
1744
|
+
mediaHosts(options) {
|
|
1745
|
+
return (options?.client ?? this.client).get({
|
|
1746
|
+
url: "/config/media-hosts",
|
|
1747
|
+
...options
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1659
1750
|
systemContract(parameters, options) {
|
|
1660
1751
|
const params = buildClientParams([parameters], [
|
|
1661
1752
|
{
|
|
@@ -1967,41 +2058,10 @@ class Mechanic extends HeyApiClient {
|
|
|
1967
2058
|
}
|
|
1968
2059
|
|
|
1969
2060
|
class Media extends HeyApiClient {
|
|
1970
|
-
|
|
1971
|
-
const params = buildClientParams([parameters], [
|
|
1972
|
-
{
|
|
1973
|
-
args: [
|
|
1974
|
-
{ in: "body", key: "kind" },
|
|
1975
|
-
{ in: "body", key: "scope" },
|
|
1976
|
-
{ in: "body", key: "fileName" },
|
|
1977
|
-
{ in: "body", key: "mimeType" },
|
|
1978
|
-
{ in: "body", key: "fileSize" }
|
|
1979
|
-
]
|
|
1980
|
-
}
|
|
1981
|
-
]);
|
|
1982
|
-
return (options?.client ?? this.client).post({
|
|
1983
|
-
url: "/media/upload-session",
|
|
1984
|
-
...options,
|
|
1985
|
-
...params,
|
|
1986
|
-
headers: {
|
|
1987
|
-
"Content-Type": "application/json",
|
|
1988
|
-
...options?.headers,
|
|
1989
|
-
...params.headers
|
|
1990
|
-
}
|
|
1991
|
-
});
|
|
1992
|
-
}
|
|
1993
|
-
upload(parameters, options) {
|
|
1994
|
-
const params = buildClientParams([parameters], [{ args: [{ in: "path", key: "mediaId" }] }]);
|
|
1995
|
-
return (options?.client ?? this.client).put({
|
|
1996
|
-
url: "/media/{mediaId}/upload",
|
|
1997
|
-
...options,
|
|
1998
|
-
...params
|
|
1999
|
-
});
|
|
2000
|
-
}
|
|
2001
|
-
process(parameters, options) {
|
|
2061
|
+
finalizeUpload(parameters, options) {
|
|
2002
2062
|
const params = buildClientParams([parameters], [{ args: [{ in: "path", key: "mediaId" }] }]);
|
|
2003
2063
|
return (options?.client ?? this.client).post({
|
|
2004
|
-
url: "/media/{mediaId}/
|
|
2064
|
+
url: "/media/{mediaId}/finalize",
|
|
2005
2065
|
...options,
|
|
2006
2066
|
...params
|
|
2007
2067
|
});
|
|
@@ -2103,6 +2163,29 @@ class Siwe extends HeyApiClient {
|
|
|
2103
2163
|
}
|
|
2104
2164
|
|
|
2105
2165
|
class User extends HeyApiClient {
|
|
2166
|
+
createMediaUploadSession(parameters, options) {
|
|
2167
|
+
const params = buildClientParams([parameters], [
|
|
2168
|
+
{
|
|
2169
|
+
args: [
|
|
2170
|
+
{ in: "body", key: "purpose" },
|
|
2171
|
+
{ in: "body", key: "fileName" },
|
|
2172
|
+
{ in: "body", key: "mimeType" },
|
|
2173
|
+
{ in: "body", key: "fileSize" },
|
|
2174
|
+
{ in: "body", key: "contentHash" }
|
|
2175
|
+
]
|
|
2176
|
+
}
|
|
2177
|
+
]);
|
|
2178
|
+
return (options?.client ?? this.client).post({
|
|
2179
|
+
url: "/user/media/upload-session",
|
|
2180
|
+
...options,
|
|
2181
|
+
...params,
|
|
2182
|
+
headers: {
|
|
2183
|
+
"Content-Type": "application/json",
|
|
2184
|
+
...options?.headers,
|
|
2185
|
+
...params.headers
|
|
2186
|
+
}
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2106
2189
|
signin(parameters, options) {
|
|
2107
2190
|
const params = buildClientParams([parameters], [{ args: [{ key: "body", map: "body" }] }]);
|
|
2108
2191
|
return (options?.client ?? this.client).post({
|
|
@@ -2122,6 +2205,62 @@ class User extends HeyApiClient {
|
|
|
2122
2205
|
}
|
|
2123
2206
|
}
|
|
2124
2207
|
|
|
2208
|
+
class Profile extends HeyApiClient {
|
|
2209
|
+
get(options) {
|
|
2210
|
+
return (options?.client ?? this.client).get({ url: "/user/profile", ...options });
|
|
2211
|
+
}
|
|
2212
|
+
update(parameters, options) {
|
|
2213
|
+
const params = buildClientParams([parameters], [
|
|
2214
|
+
{
|
|
2215
|
+
args: [
|
|
2216
|
+
{ in: "body", key: "displayName" },
|
|
2217
|
+
{ in: "body", key: "bio" },
|
|
2218
|
+
{ in: "body", key: "website" },
|
|
2219
|
+
{ in: "body", key: "avatarMediaId" }
|
|
2220
|
+
]
|
|
2221
|
+
}
|
|
2222
|
+
]);
|
|
2223
|
+
return (options?.client ?? this.client).patch({
|
|
2224
|
+
url: "/user/profile",
|
|
2225
|
+
...options,
|
|
2226
|
+
...params,
|
|
2227
|
+
headers: {
|
|
2228
|
+
"Content-Type": "application/json",
|
|
2229
|
+
...options?.headers,
|
|
2230
|
+
...params.headers
|
|
2231
|
+
}
|
|
2232
|
+
});
|
|
2233
|
+
}
|
|
2234
|
+
public(parameters, options) {
|
|
2235
|
+
const params = buildClientParams([parameters], [{ args: [{ in: "path", key: "walletAddress" }] }]);
|
|
2236
|
+
return (options?.client ?? this.client).get({
|
|
2237
|
+
url: "/user/{walletAddress}/profile",
|
|
2238
|
+
...options,
|
|
2239
|
+
...params
|
|
2240
|
+
});
|
|
2241
|
+
}
|
|
2242
|
+
tokens(parameters, options) {
|
|
2243
|
+
const params = buildClientParams([parameters], [
|
|
2244
|
+
{
|
|
2245
|
+
args: [
|
|
2246
|
+
{ in: "path", key: "walletAddress" },
|
|
2247
|
+
{ in: "query", key: "page" },
|
|
2248
|
+
{ in: "query", key: "limit" },
|
|
2249
|
+
{ in: "query", key: "sort" },
|
|
2250
|
+
{ in: "query", key: "order" },
|
|
2251
|
+
{ in: "query", key: "collectionId" },
|
|
2252
|
+
{ in: "query", key: "search" }
|
|
2253
|
+
]
|
|
2254
|
+
}
|
|
2255
|
+
]);
|
|
2256
|
+
return (options?.client ?? this.client).get({
|
|
2257
|
+
url: "/user/{walletAddress}/tokens",
|
|
2258
|
+
...options,
|
|
2259
|
+
...params
|
|
2260
|
+
});
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2125
2264
|
class ApiKey extends HeyApiClient {
|
|
2126
2265
|
list(options) {
|
|
2127
2266
|
return (options?.client ?? this.client).get({ url: "/user/api-keys", ...options });
|
|
@@ -2243,6 +2382,10 @@ class HighlightClient extends HeyApiClient {
|
|
|
2243
2382
|
get user() {
|
|
2244
2383
|
return this._user ??= new User({ client: this.client });
|
|
2245
2384
|
}
|
|
2385
|
+
_profile;
|
|
2386
|
+
get profile() {
|
|
2387
|
+
return this._profile ??= new Profile({ client: this.client });
|
|
2388
|
+
}
|
|
2246
2389
|
_apiKey;
|
|
2247
2390
|
get apiKey() {
|
|
2248
2391
|
return this._apiKey ??= new ApiKey({ client: this.client });
|
|
@@ -2263,7 +2406,406 @@ function createHighlightClient(config) {
|
|
|
2263
2406
|
const client2 = createClient(resolvedConfig);
|
|
2264
2407
|
return new HighlightClient({ client: client2 });
|
|
2265
2408
|
}
|
|
2409
|
+
// ../../node_modules/@noble/hashes/esm/utils.js
|
|
2410
|
+
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2411
|
+
function isBytes(a) {
|
|
2412
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
2413
|
+
}
|
|
2414
|
+
function abytes(b, ...lengths) {
|
|
2415
|
+
if (!isBytes(b))
|
|
2416
|
+
throw new Error("Uint8Array expected");
|
|
2417
|
+
if (lengths.length > 0 && !lengths.includes(b.length))
|
|
2418
|
+
throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
|
|
2419
|
+
}
|
|
2420
|
+
function aexists(instance, checkFinished = true) {
|
|
2421
|
+
if (instance.destroyed)
|
|
2422
|
+
throw new Error("Hash instance has been destroyed");
|
|
2423
|
+
if (checkFinished && instance.finished)
|
|
2424
|
+
throw new Error("Hash#digest() has already been called");
|
|
2425
|
+
}
|
|
2426
|
+
function aoutput(out, instance) {
|
|
2427
|
+
abytes(out);
|
|
2428
|
+
const min = instance.outputLen;
|
|
2429
|
+
if (out.length < min) {
|
|
2430
|
+
throw new Error("digestInto() expects output buffer of length at least " + min);
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
function clean(...arrays) {
|
|
2434
|
+
for (let i = 0;i < arrays.length; i++) {
|
|
2435
|
+
arrays[i].fill(0);
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
function createView(arr) {
|
|
2439
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
2440
|
+
}
|
|
2441
|
+
function rotr(word, shift) {
|
|
2442
|
+
return word << 32 - shift | word >>> shift;
|
|
2443
|
+
}
|
|
2444
|
+
var hasHexBuiltin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function")();
|
|
2445
|
+
var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
2446
|
+
function bytesToHex(bytes) {
|
|
2447
|
+
abytes(bytes);
|
|
2448
|
+
if (hasHexBuiltin)
|
|
2449
|
+
return bytes.toHex();
|
|
2450
|
+
let hex = "";
|
|
2451
|
+
for (let i = 0;i < bytes.length; i++) {
|
|
2452
|
+
hex += hexes[bytes[i]];
|
|
2453
|
+
}
|
|
2454
|
+
return hex;
|
|
2455
|
+
}
|
|
2456
|
+
function utf8ToBytes(str) {
|
|
2457
|
+
if (typeof str !== "string")
|
|
2458
|
+
throw new Error("string expected");
|
|
2459
|
+
return new Uint8Array(new TextEncoder().encode(str));
|
|
2460
|
+
}
|
|
2461
|
+
function toBytes(data) {
|
|
2462
|
+
if (typeof data === "string")
|
|
2463
|
+
data = utf8ToBytes(data);
|
|
2464
|
+
abytes(data);
|
|
2465
|
+
return data;
|
|
2466
|
+
}
|
|
2467
|
+
class Hash {
|
|
2468
|
+
}
|
|
2469
|
+
function createHasher(hashCons) {
|
|
2470
|
+
const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
|
|
2471
|
+
const tmp = hashCons();
|
|
2472
|
+
hashC.outputLen = tmp.outputLen;
|
|
2473
|
+
hashC.blockLen = tmp.blockLen;
|
|
2474
|
+
hashC.create = () => hashCons();
|
|
2475
|
+
return hashC;
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
// ../../node_modules/@noble/hashes/esm/_md.js
|
|
2479
|
+
function setBigUint64(view, byteOffset, value, isLE) {
|
|
2480
|
+
if (typeof view.setBigUint64 === "function")
|
|
2481
|
+
return view.setBigUint64(byteOffset, value, isLE);
|
|
2482
|
+
const _32n = BigInt(32);
|
|
2483
|
+
const _u32_max = BigInt(4294967295);
|
|
2484
|
+
const wh = Number(value >> _32n & _u32_max);
|
|
2485
|
+
const wl = Number(value & _u32_max);
|
|
2486
|
+
const h = isLE ? 4 : 0;
|
|
2487
|
+
const l = isLE ? 0 : 4;
|
|
2488
|
+
view.setUint32(byteOffset + h, wh, isLE);
|
|
2489
|
+
view.setUint32(byteOffset + l, wl, isLE);
|
|
2490
|
+
}
|
|
2491
|
+
function Chi(a, b, c) {
|
|
2492
|
+
return a & b ^ ~a & c;
|
|
2493
|
+
}
|
|
2494
|
+
function Maj(a, b, c) {
|
|
2495
|
+
return a & b ^ a & c ^ b & c;
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2498
|
+
class HashMD extends Hash {
|
|
2499
|
+
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
2500
|
+
super();
|
|
2501
|
+
this.finished = false;
|
|
2502
|
+
this.length = 0;
|
|
2503
|
+
this.pos = 0;
|
|
2504
|
+
this.destroyed = false;
|
|
2505
|
+
this.blockLen = blockLen;
|
|
2506
|
+
this.outputLen = outputLen;
|
|
2507
|
+
this.padOffset = padOffset;
|
|
2508
|
+
this.isLE = isLE;
|
|
2509
|
+
this.buffer = new Uint8Array(blockLen);
|
|
2510
|
+
this.view = createView(this.buffer);
|
|
2511
|
+
}
|
|
2512
|
+
update(data) {
|
|
2513
|
+
aexists(this);
|
|
2514
|
+
data = toBytes(data);
|
|
2515
|
+
abytes(data);
|
|
2516
|
+
const { view, buffer, blockLen } = this;
|
|
2517
|
+
const len = data.length;
|
|
2518
|
+
for (let pos = 0;pos < len; ) {
|
|
2519
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
2520
|
+
if (take === blockLen) {
|
|
2521
|
+
const dataView = createView(data);
|
|
2522
|
+
for (;blockLen <= len - pos; pos += blockLen)
|
|
2523
|
+
this.process(dataView, pos);
|
|
2524
|
+
continue;
|
|
2525
|
+
}
|
|
2526
|
+
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
2527
|
+
this.pos += take;
|
|
2528
|
+
pos += take;
|
|
2529
|
+
if (this.pos === blockLen) {
|
|
2530
|
+
this.process(view, 0);
|
|
2531
|
+
this.pos = 0;
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
this.length += data.length;
|
|
2535
|
+
this.roundClean();
|
|
2536
|
+
return this;
|
|
2537
|
+
}
|
|
2538
|
+
digestInto(out) {
|
|
2539
|
+
aexists(this);
|
|
2540
|
+
aoutput(out, this);
|
|
2541
|
+
this.finished = true;
|
|
2542
|
+
const { buffer, view, blockLen, isLE } = this;
|
|
2543
|
+
let { pos } = this;
|
|
2544
|
+
buffer[pos++] = 128;
|
|
2545
|
+
clean(this.buffer.subarray(pos));
|
|
2546
|
+
if (this.padOffset > blockLen - pos) {
|
|
2547
|
+
this.process(view, 0);
|
|
2548
|
+
pos = 0;
|
|
2549
|
+
}
|
|
2550
|
+
for (let i = pos;i < blockLen; i++)
|
|
2551
|
+
buffer[i] = 0;
|
|
2552
|
+
setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
|
|
2553
|
+
this.process(view, 0);
|
|
2554
|
+
const oview = createView(out);
|
|
2555
|
+
const len = this.outputLen;
|
|
2556
|
+
if (len % 4)
|
|
2557
|
+
throw new Error("_sha2: outputLen should be aligned to 32bit");
|
|
2558
|
+
const outLen = len / 4;
|
|
2559
|
+
const state = this.get();
|
|
2560
|
+
if (outLen > state.length)
|
|
2561
|
+
throw new Error("_sha2: outputLen bigger than state");
|
|
2562
|
+
for (let i = 0;i < outLen; i++)
|
|
2563
|
+
oview.setUint32(4 * i, state[i], isLE);
|
|
2564
|
+
}
|
|
2565
|
+
digest() {
|
|
2566
|
+
const { buffer, outputLen } = this;
|
|
2567
|
+
this.digestInto(buffer);
|
|
2568
|
+
const res = buffer.slice(0, outputLen);
|
|
2569
|
+
this.destroy();
|
|
2570
|
+
return res;
|
|
2571
|
+
}
|
|
2572
|
+
_cloneInto(to) {
|
|
2573
|
+
to || (to = new this.constructor);
|
|
2574
|
+
to.set(...this.get());
|
|
2575
|
+
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
2576
|
+
to.destroyed = destroyed;
|
|
2577
|
+
to.finished = finished;
|
|
2578
|
+
to.length = length;
|
|
2579
|
+
to.pos = pos;
|
|
2580
|
+
if (length % blockLen)
|
|
2581
|
+
to.buffer.set(buffer);
|
|
2582
|
+
return to;
|
|
2583
|
+
}
|
|
2584
|
+
clone() {
|
|
2585
|
+
return this._cloneInto();
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
2589
|
+
1779033703,
|
|
2590
|
+
3144134277,
|
|
2591
|
+
1013904242,
|
|
2592
|
+
2773480762,
|
|
2593
|
+
1359893119,
|
|
2594
|
+
2600822924,
|
|
2595
|
+
528734635,
|
|
2596
|
+
1541459225
|
|
2597
|
+
]);
|
|
2598
|
+
|
|
2599
|
+
// ../../node_modules/@noble/hashes/esm/sha2.js
|
|
2600
|
+
var SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
2601
|
+
1116352408,
|
|
2602
|
+
1899447441,
|
|
2603
|
+
3049323471,
|
|
2604
|
+
3921009573,
|
|
2605
|
+
961987163,
|
|
2606
|
+
1508970993,
|
|
2607
|
+
2453635748,
|
|
2608
|
+
2870763221,
|
|
2609
|
+
3624381080,
|
|
2610
|
+
310598401,
|
|
2611
|
+
607225278,
|
|
2612
|
+
1426881987,
|
|
2613
|
+
1925078388,
|
|
2614
|
+
2162078206,
|
|
2615
|
+
2614888103,
|
|
2616
|
+
3248222580,
|
|
2617
|
+
3835390401,
|
|
2618
|
+
4022224774,
|
|
2619
|
+
264347078,
|
|
2620
|
+
604807628,
|
|
2621
|
+
770255983,
|
|
2622
|
+
1249150122,
|
|
2623
|
+
1555081692,
|
|
2624
|
+
1996064986,
|
|
2625
|
+
2554220882,
|
|
2626
|
+
2821834349,
|
|
2627
|
+
2952996808,
|
|
2628
|
+
3210313671,
|
|
2629
|
+
3336571891,
|
|
2630
|
+
3584528711,
|
|
2631
|
+
113926993,
|
|
2632
|
+
338241895,
|
|
2633
|
+
666307205,
|
|
2634
|
+
773529912,
|
|
2635
|
+
1294757372,
|
|
2636
|
+
1396182291,
|
|
2637
|
+
1695183700,
|
|
2638
|
+
1986661051,
|
|
2639
|
+
2177026350,
|
|
2640
|
+
2456956037,
|
|
2641
|
+
2730485921,
|
|
2642
|
+
2820302411,
|
|
2643
|
+
3259730800,
|
|
2644
|
+
3345764771,
|
|
2645
|
+
3516065817,
|
|
2646
|
+
3600352804,
|
|
2647
|
+
4094571909,
|
|
2648
|
+
275423344,
|
|
2649
|
+
430227734,
|
|
2650
|
+
506948616,
|
|
2651
|
+
659060556,
|
|
2652
|
+
883997877,
|
|
2653
|
+
958139571,
|
|
2654
|
+
1322822218,
|
|
2655
|
+
1537002063,
|
|
2656
|
+
1747873779,
|
|
2657
|
+
1955562222,
|
|
2658
|
+
2024104815,
|
|
2659
|
+
2227730452,
|
|
2660
|
+
2361852424,
|
|
2661
|
+
2428436474,
|
|
2662
|
+
2756734187,
|
|
2663
|
+
3204031479,
|
|
2664
|
+
3329325298
|
|
2665
|
+
]);
|
|
2666
|
+
var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
2667
|
+
|
|
2668
|
+
class SHA256 extends HashMD {
|
|
2669
|
+
constructor(outputLen = 32) {
|
|
2670
|
+
super(64, outputLen, 8, false);
|
|
2671
|
+
this.A = SHA256_IV[0] | 0;
|
|
2672
|
+
this.B = SHA256_IV[1] | 0;
|
|
2673
|
+
this.C = SHA256_IV[2] | 0;
|
|
2674
|
+
this.D = SHA256_IV[3] | 0;
|
|
2675
|
+
this.E = SHA256_IV[4] | 0;
|
|
2676
|
+
this.F = SHA256_IV[5] | 0;
|
|
2677
|
+
this.G = SHA256_IV[6] | 0;
|
|
2678
|
+
this.H = SHA256_IV[7] | 0;
|
|
2679
|
+
}
|
|
2680
|
+
get() {
|
|
2681
|
+
const { A, B, C, D, E, F, G, H } = this;
|
|
2682
|
+
return [A, B, C, D, E, F, G, H];
|
|
2683
|
+
}
|
|
2684
|
+
set(A, B, C, D, E, F, G, H) {
|
|
2685
|
+
this.A = A | 0;
|
|
2686
|
+
this.B = B | 0;
|
|
2687
|
+
this.C = C | 0;
|
|
2688
|
+
this.D = D | 0;
|
|
2689
|
+
this.E = E | 0;
|
|
2690
|
+
this.F = F | 0;
|
|
2691
|
+
this.G = G | 0;
|
|
2692
|
+
this.H = H | 0;
|
|
2693
|
+
}
|
|
2694
|
+
process(view, offset) {
|
|
2695
|
+
for (let i = 0;i < 16; i++, offset += 4)
|
|
2696
|
+
SHA256_W[i] = view.getUint32(offset, false);
|
|
2697
|
+
for (let i = 16;i < 64; i++) {
|
|
2698
|
+
const W15 = SHA256_W[i - 15];
|
|
2699
|
+
const W2 = SHA256_W[i - 2];
|
|
2700
|
+
const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
|
|
2701
|
+
const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
|
|
2702
|
+
SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
|
|
2703
|
+
}
|
|
2704
|
+
let { A, B, C, D, E, F, G, H } = this;
|
|
2705
|
+
for (let i = 0;i < 64; i++) {
|
|
2706
|
+
const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
|
|
2707
|
+
const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i] | 0;
|
|
2708
|
+
const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
|
|
2709
|
+
const T2 = sigma0 + Maj(A, B, C) | 0;
|
|
2710
|
+
H = G;
|
|
2711
|
+
G = F;
|
|
2712
|
+
F = E;
|
|
2713
|
+
E = D + T1 | 0;
|
|
2714
|
+
D = C;
|
|
2715
|
+
C = B;
|
|
2716
|
+
B = A;
|
|
2717
|
+
A = T1 + T2 | 0;
|
|
2718
|
+
}
|
|
2719
|
+
A = A + this.A | 0;
|
|
2720
|
+
B = B + this.B | 0;
|
|
2721
|
+
C = C + this.C | 0;
|
|
2722
|
+
D = D + this.D | 0;
|
|
2723
|
+
E = E + this.E | 0;
|
|
2724
|
+
F = F + this.F | 0;
|
|
2725
|
+
G = G + this.G | 0;
|
|
2726
|
+
H = H + this.H | 0;
|
|
2727
|
+
this.set(A, B, C, D, E, F, G, H);
|
|
2728
|
+
}
|
|
2729
|
+
roundClean() {
|
|
2730
|
+
clean(SHA256_W);
|
|
2731
|
+
}
|
|
2732
|
+
destroy() {
|
|
2733
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
2734
|
+
clean(this.buffer);
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
var sha256 = /* @__PURE__ */ createHasher(() => new SHA256);
|
|
2738
|
+
|
|
2266
2739
|
// ../sdk/src/v1/media.ts
|
|
2740
|
+
var isReadableStream = (source) => ("getReader" in source);
|
|
2741
|
+
var sha256MediaContent = async (source, options) => {
|
|
2742
|
+
const hasher = sha256.create();
|
|
2743
|
+
let bytesHashed = 0;
|
|
2744
|
+
const update = (chunk) => {
|
|
2745
|
+
if (options?.signal?.aborted) {
|
|
2746
|
+
throw new DOMException("Hashing aborted.", "AbortError");
|
|
2747
|
+
}
|
|
2748
|
+
hasher.update(chunk);
|
|
2749
|
+
bytesHashed += chunk.byteLength;
|
|
2750
|
+
options?.onProgress?.(bytesHashed);
|
|
2751
|
+
};
|
|
2752
|
+
if (isReadableStream(source)) {
|
|
2753
|
+
const reader = source.getReader();
|
|
2754
|
+
try {
|
|
2755
|
+
while (true) {
|
|
2756
|
+
const result = await reader.read();
|
|
2757
|
+
if (result.done)
|
|
2758
|
+
break;
|
|
2759
|
+
update(result.value);
|
|
2760
|
+
}
|
|
2761
|
+
} finally {
|
|
2762
|
+
reader.releaseLock();
|
|
2763
|
+
}
|
|
2764
|
+
} else {
|
|
2765
|
+
for await (const chunk of source)
|
|
2766
|
+
update(chunk);
|
|
2767
|
+
}
|
|
2768
|
+
return `sha256:${bytesToHex(hasher.digest())}`;
|
|
2769
|
+
};
|
|
2770
|
+
var SUPPORTED_IMAGE_CONTENT_TYPES = new Set([
|
|
2771
|
+
"image/avif",
|
|
2772
|
+
"image/gif",
|
|
2773
|
+
"image/heic",
|
|
2774
|
+
"image/heif",
|
|
2775
|
+
"image/jpeg",
|
|
2776
|
+
"image/jpg",
|
|
2777
|
+
"image/png",
|
|
2778
|
+
"image/webp"
|
|
2779
|
+
]);
|
|
2780
|
+
var DEFAULT_MEDIA_DELIVERY_HOSTS = {
|
|
2781
|
+
assets: "https://assets.highlight.xyz",
|
|
2782
|
+
metadata: "https://metadata.highlight.xyz",
|
|
2783
|
+
legacyAssets: "https://highlight-creator-assets.highlight.xyz",
|
|
2784
|
+
arweaveGateway: "https://arweave.net",
|
|
2785
|
+
ipfsGateway: "https://ipfs.io"
|
|
2786
|
+
};
|
|
2787
|
+
var LEGACY_REFERENCE = /^main\//;
|
|
2788
|
+
var mediaUrl = (media, location, hosts = DEFAULT_MEDIA_DELIVERY_HOSTS) => {
|
|
2789
|
+
switch (location.provider) {
|
|
2790
|
+
case "R2" /* R2 */: {
|
|
2791
|
+
if (LEGACY_REFERENCE.test(location.reference)) {
|
|
2792
|
+
return `${hosts.legacyAssets}/${location.reference}`;
|
|
2793
|
+
}
|
|
2794
|
+
if (media.parentId && media.path) {
|
|
2795
|
+
return `${hosts.assets}/${media.parentId}/${media.path}`;
|
|
2796
|
+
}
|
|
2797
|
+
return media.kind === "Directory" /* Directory */ ? `${hosts.assets}/${media.id}/` : `${hosts.assets}/${media.id}`;
|
|
2798
|
+
}
|
|
2799
|
+
case "Arweave" /* Arweave */:
|
|
2800
|
+
return `${hosts.arweaveGateway}/${location.reference}`;
|
|
2801
|
+
case "IPFS" /* Ipfs */:
|
|
2802
|
+
return `${hosts.ipfsGateway}/ipfs/${location.reference.replace(/^ipfs:\/\//, "").replace(/^\//, "")}`;
|
|
2803
|
+
case "External" /* External */:
|
|
2804
|
+
return location.reference;
|
|
2805
|
+
default:
|
|
2806
|
+
return null;
|
|
2807
|
+
}
|
|
2808
|
+
};
|
|
2267
2809
|
var DEFAULT_PREFERENCE = [
|
|
2268
2810
|
"Archive" /* Archive */,
|
|
2269
2811
|
"Origin" /* Origin */,
|
|
@@ -2271,7 +2813,7 @@ var DEFAULT_PREFERENCE = [
|
|
|
2271
2813
|
];
|
|
2272
2814
|
var pickLocation = (media, preference) => {
|
|
2273
2815
|
for (const role of preference) {
|
|
2274
|
-
const location = media.locations.find((l) => l.role === role && l.status === "Succeeded" /* Succeeded */
|
|
2816
|
+
const location = media.locations.find((l) => l.role === role && l.status === "Succeeded" /* Succeeded */);
|
|
2275
2817
|
if (location)
|
|
2276
2818
|
return location;
|
|
2277
2819
|
}
|
|
@@ -2281,12 +2823,13 @@ var resolveMediaUrl = (media, options) => {
|
|
|
2281
2823
|
if (!media)
|
|
2282
2824
|
return null;
|
|
2283
2825
|
const preference = options?.prefer ? Array.isArray(options.prefer) ? options.prefer : [options.prefer] : DEFAULT_PREFERENCE;
|
|
2284
|
-
|
|
2826
|
+
const location = pickLocation(media, preference);
|
|
2827
|
+
return location ? mediaUrl(media, location, options?.hosts) : null;
|
|
2285
2828
|
};
|
|
2286
2829
|
// src/config.ts
|
|
2287
2830
|
import { chmod, mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
2288
2831
|
import path from "node:path";
|
|
2289
|
-
var DEFAULT_API_URL = "https://api.
|
|
2832
|
+
var DEFAULT_API_URL = "https://api.highlight.xyz";
|
|
2290
2833
|
var CONFIG_VERSION = 1;
|
|
2291
2834
|
var defaultConfig = () => ({
|
|
2292
2835
|
currentProfile: "default",
|
|
@@ -2693,7 +3236,7 @@ var requiredInputPath = (inputPath) => {
|
|
|
2693
3236
|
var isCollectionCreateInput = (value) => {
|
|
2694
3237
|
if (!isRecord3(value))
|
|
2695
3238
|
return false;
|
|
2696
|
-
if (typeof value.name !== "string" || typeof value.description !== "string" || typeof value.logoMediaId !== "string" ||
|
|
3239
|
+
if (typeof value.name !== "string" || typeof value.description !== "string" || typeof value.logoMediaId !== "string" || !Object.values(CollectionType).includes(value.type) || !isOptionalString(value.contractId) || !isOptionalString(value.tokenManager)) {
|
|
2697
3240
|
return false;
|
|
2698
3241
|
}
|
|
2699
3242
|
if (value.contract !== undefined) {
|
|
@@ -2782,7 +3325,7 @@ var create = async (args, global, runtime) => {
|
|
|
2782
3325
|
});
|
|
2783
3326
|
assertNoExtraPositionals(parsed.positionals, 0);
|
|
2784
3327
|
const inputPath = requiredInputPath(parsed.values.input);
|
|
2785
|
-
const input = await readTypedJsonInput(inputPath, runtime, isCollectionCreateInput, "a collection.create object containing name, description, logoMediaId,
|
|
3328
|
+
const input = await readTypedJsonInput(inputPath, runtime, isCollectionCreateInput, "a collection.create object containing name, description, logoMediaId, type, and valid contract details");
|
|
2786
3329
|
const context = await createClientContext(runtime, global);
|
|
2787
3330
|
const collection = unwrap(await context.client.collection.create(input));
|
|
2788
3331
|
if (global.json) {
|
|
@@ -3000,8 +3543,10 @@ var remove = async (args, global, runtime) => {
|
|
|
3000
3543
|
};
|
|
3001
3544
|
|
|
3002
3545
|
// src/commands/media.ts
|
|
3003
|
-
import {
|
|
3546
|
+
import { createReadStream } from "node:fs";
|
|
3547
|
+
import { stat } from "node:fs/promises";
|
|
3004
3548
|
import path3 from "node:path";
|
|
3549
|
+
import { Readable } from "node:stream";
|
|
3005
3550
|
var MIME_TYPES = {
|
|
3006
3551
|
".css": "text/css",
|
|
3007
3552
|
".gif": "image/gif",
|
|
@@ -3047,11 +3592,11 @@ var waitUntilReady = async (mediaId, initial, timeoutSeconds, pollIntervalSecond
|
|
|
3047
3592
|
var upload = async (args, global, runtime) => {
|
|
3048
3593
|
const parsed = parseCommandArgs(args, {
|
|
3049
3594
|
options: {
|
|
3050
|
-
|
|
3595
|
+
collection: { type: "string" },
|
|
3051
3596
|
"mime-type": { type: "string" },
|
|
3052
3597
|
"no-wait": { type: "boolean" },
|
|
3053
3598
|
"poll-interval": { type: "string" },
|
|
3054
|
-
|
|
3599
|
+
purpose: { type: "string" },
|
|
3055
3600
|
timeout: { type: "string" }
|
|
3056
3601
|
}
|
|
3057
3602
|
});
|
|
@@ -3062,40 +3607,45 @@ var upload = async (args, global, runtime) => {
|
|
|
3062
3607
|
if (!fileStat.isFile()) {
|
|
3063
3608
|
throw new CliError(`Media input must be a file: ${inputPath}`, 2);
|
|
3064
3609
|
}
|
|
3065
|
-
const
|
|
3066
|
-
const
|
|
3067
|
-
if (!
|
|
3068
|
-
throw new CliError(
|
|
3610
|
+
const purposes = Object.values(MediaPurpose);
|
|
3611
|
+
const purpose = purposes.find((value) => value === parsed.values.purpose);
|
|
3612
|
+
if (!purpose) {
|
|
3613
|
+
throw new CliError(`--purpose must be one of: ${purposes.join(", ")}`, 2);
|
|
3069
3614
|
}
|
|
3070
|
-
|
|
3071
|
-
|
|
3615
|
+
const collectionId = parsed.values.collection;
|
|
3616
|
+
const needsCollection = purpose !== "UserAvatar" /* UserAvatar */;
|
|
3617
|
+
if (needsCollection && !collectionId) {
|
|
3618
|
+
throw new CliError(`--collection is required for ${purpose} uploads`, 2);
|
|
3072
3619
|
}
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
if (!scope) {
|
|
3076
|
-
throw new CliError('--scope must be either "collection" or "user"', 2);
|
|
3620
|
+
if (!needsCollection && collectionId) {
|
|
3621
|
+
throw new CliError(`--collection is not valid for ${purpose} uploads`, 2);
|
|
3077
3622
|
}
|
|
3623
|
+
const contentHash = await sha256MediaContent(createReadStream(absolutePath));
|
|
3078
3624
|
const context = await createClientContext(runtime, global);
|
|
3079
|
-
const
|
|
3625
|
+
const body = {
|
|
3080
3626
|
fileName: path3.basename(absolutePath),
|
|
3081
3627
|
fileSize: fileStat.size,
|
|
3082
|
-
kind,
|
|
3083
3628
|
mimeType: parsed.values["mime-type"] ?? mimeTypeFor(absolutePath),
|
|
3084
|
-
|
|
3085
|
-
|
|
3629
|
+
purpose,
|
|
3630
|
+
contentHash
|
|
3631
|
+
};
|
|
3632
|
+
const session = unwrap(collectionId ? await context.client.collection.createMediaUploadSession({
|
|
3633
|
+
highlightId: collectionId,
|
|
3634
|
+
...body
|
|
3635
|
+
}) : await context.client.user.createMediaUploadSession(body));
|
|
3086
3636
|
const headers = new Headers(session.upload.headers);
|
|
3087
|
-
if (!headers.has("authorization")) {
|
|
3088
|
-
headers.set("authorization", `Bearer ${context.apiKey}`);
|
|
3089
|
-
}
|
|
3090
3637
|
const response = await runtime.fetch(session.upload.url, {
|
|
3091
|
-
body:
|
|
3638
|
+
body: Readable.toWeb(createReadStream(absolutePath)),
|
|
3639
|
+
duplex: "half",
|
|
3092
3640
|
headers,
|
|
3093
3641
|
method: session.upload.method
|
|
3094
3642
|
});
|
|
3095
3643
|
if (!response.ok) {
|
|
3096
3644
|
throw new ApiError(await parseResponseError(response), response.status);
|
|
3097
3645
|
}
|
|
3098
|
-
let media2 = unwrap(await context.client.media.
|
|
3646
|
+
let media2 = unwrap(await context.client.media.finalizeUpload({
|
|
3647
|
+
mediaId: session.uploadMediaId
|
|
3648
|
+
}));
|
|
3099
3649
|
if (!parsed.values["no-wait"]) {
|
|
3100
3650
|
media2 = await waitUntilReady(media2.id, media2, positiveNumber(parsed.values.timeout, "--timeout") ?? 300, positiveNumber(parsed.values["poll-interval"], "--poll-interval") ?? 2, runtime, async () => unwrap(await context.client.media.get({ mediaId: media2.id })));
|
|
3101
3651
|
}
|
|
@@ -3139,7 +3689,7 @@ var isOptionalBoolean = (value) => value === undefined || typeof value === "bool
|
|
|
3139
3689
|
var isSaleCreateInput = (value) => {
|
|
3140
3690
|
if (!isRecord3(value))
|
|
3141
3691
|
return false;
|
|
3142
|
-
return Object.values(SaleType).includes(value.type) && typeof value.startAt === "string" && typeof value.price === "string" && typeof value.currency === "string" && typeof value.maxPerTransaction === "number" && Number.isFinite(value.maxPerTransaction) && typeof value.maxPerWallet === "number" && Number.isFinite(value.maxPerWallet) && typeof value.maxTotal === "number" && Number.isFinite(value.maxTotal) && typeof value.paymentRecipient === "string" && isOptionalNullableString(value.name) && isOptionalNullableString(value.endAt) && (value.accessMode === undefined || Object.values(SaleAccessMode).includes(value.accessMode)) && isOptionalNullableString(value.gateId) &&
|
|
3692
|
+
return Object.values(SaleType).includes(value.type) && typeof value.startAt === "string" && typeof value.price === "string" && typeof value.currency === "string" && typeof value.maxPerTransaction === "number" && Number.isFinite(value.maxPerTransaction) && typeof value.maxPerWallet === "number" && Number.isFinite(value.maxPerWallet) && typeof value.maxTotal === "number" && Number.isFinite(value.maxTotal) && typeof value.paymentRecipient === "string" && isOptionalNullableString(value.name) && isOptionalNullableString(value.endAt) && (value.accessMode === undefined || Object.values(SaleAccessMode).includes(value.accessMode)) && isOptionalNullableString(value.gateId) && isOptionalNullableString(value.mechanicId) && isOptionalNullableString(value.collectorMessage) && isOptionalNullableString(value.customMintFee);
|
|
3143
3693
|
};
|
|
3144
3694
|
var SALE_UPDATE_FIELDS = [
|
|
3145
3695
|
"name",
|
|
@@ -3490,8 +4040,10 @@ var MEDIA_HELP = `Usage:
|
|
|
3490
4040
|
hl media publish <media-id>
|
|
3491
4041
|
|
|
3492
4042
|
Upload options:
|
|
3493
|
-
--
|
|
3494
|
-
|
|
4043
|
+
--purpose <purpose> Required. CollectionLogo, EditionImage,
|
|
4044
|
+
EditionAnimation, SeriesAssets,
|
|
4045
|
+
GenerativeCode, or UserAvatar
|
|
4046
|
+
--collection <highlight-id> Required for every purpose except UserAvatar
|
|
3495
4047
|
--mime-type <type> Override inferred MIME type
|
|
3496
4048
|
--no-wait Return before processing is ready
|
|
3497
4049
|
--timeout <seconds> Wait timeout (default: 300)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@highlightxyz/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Official command-line interface for the Highlight API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -16,13 +16,16 @@
|
|
|
16
16
|
"url": "https://github.com/highlight-xyz/highlight-app.git",
|
|
17
17
|
"directory": "packages/cli"
|
|
18
18
|
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"hl": "./lib/index.js"
|
|
21
|
+
},
|
|
19
22
|
"files": [
|
|
20
23
|
"lib",
|
|
21
24
|
"README.md"
|
|
22
25
|
],
|
|
23
26
|
"type": "module",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
26
29
|
},
|
|
27
30
|
"scripts": {
|
|
28
31
|
"build": "bun build ./src/index.ts --outfile ./lib/index.js --target node --format esm",
|
|
@@ -43,8 +46,5 @@
|
|
|
43
46
|
},
|
|
44
47
|
"engines": {
|
|
45
48
|
"node": ">=20"
|
|
46
|
-
},
|
|
47
|
-
"publishConfig": {
|
|
48
|
-
"access": "public"
|
|
49
49
|
}
|
|
50
50
|
}
|