@medialane/sdk 0.103.0 → 0.105.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/dist/index.cjs +111 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -2
- package/dist/index.d.ts +58 -2
- package/dist/index.js +104 -2
- package/dist/index.js.map +1 -1
- package/dist/starknet/index.cjs +15 -0
- package/dist/starknet/index.cjs.map +1 -1
- package/dist/starknet/index.js +15 -0
- package/dist/starknet/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
var zod = require('zod');
|
|
4
4
|
var sha3_js = require('@noble/hashes/sha3.js');
|
|
5
5
|
var base = require('@scure/base');
|
|
6
|
+
var hmac_js = require('@noble/hashes/hmac.js');
|
|
7
|
+
var sha2_js = require('@noble/hashes/sha2.js');
|
|
6
8
|
|
|
7
9
|
// src/config.ts
|
|
8
10
|
|
|
@@ -1280,8 +1282,23 @@ var PUBLIC_RPC_FALLBACKS = [
|
|
|
1280
1282
|
"https://rpc.starknet.lava.build"
|
|
1281
1283
|
];
|
|
1282
1284
|
var TRANSIENT_BODY_RE = /"code"\s*:\s*-32001|"code"\s*:\s*-32603|unable to complete|rate.?limit|too many|throttl|exceed.*quota|temporarily unavailable|service unavailable|overload|gateway.*time|upstream.*time|backend.*error/i;
|
|
1285
|
+
var POLICY_REFUSAL_CODES = [-32003, -32005, -32600];
|
|
1286
|
+
function isPolicyRefusal(input) {
|
|
1287
|
+
let body = input.body;
|
|
1288
|
+
if (typeof body === "string") {
|
|
1289
|
+
try {
|
|
1290
|
+
body = JSON.parse(body);
|
|
1291
|
+
} catch {
|
|
1292
|
+
return false;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
const err = body?.error;
|
|
1296
|
+
const code = err && typeof err === "object" ? err.code : void 0;
|
|
1297
|
+
return typeof code === "number" && POLICY_REFUSAL_CODES.includes(code);
|
|
1298
|
+
}
|
|
1283
1299
|
function isTransientRpcError(input) {
|
|
1284
1300
|
const { status, body } = input;
|
|
1301
|
+
if (isPolicyRefusal({ body })) return false;
|
|
1285
1302
|
if (typeof status === "number" && (status === 429 || status >= 500)) return true;
|
|
1286
1303
|
if (body == null) return false;
|
|
1287
1304
|
if (typeof body === "object") {
|
|
@@ -1327,6 +1344,16 @@ function createFailoverFetch(urls, options = {}) {
|
|
|
1327
1344
|
};
|
|
1328
1345
|
return failover;
|
|
1329
1346
|
}
|
|
1347
|
+
var PAID_UPSTREAM_MARKERS = [
|
|
1348
|
+
"rpc.starknet.lava.build",
|
|
1349
|
+
"g.alchemy.com",
|
|
1350
|
+
"ALCHEMY_RPC_URL",
|
|
1351
|
+
"STARKNET_RPC_URL",
|
|
1352
|
+
"AVNU_PAYMASTER_API_KEY",
|
|
1353
|
+
"@avnu/avnu-sdk",
|
|
1354
|
+
"api.pinata.cloud",
|
|
1355
|
+
"PINATA_JWT"
|
|
1356
|
+
];
|
|
1330
1357
|
|
|
1331
1358
|
// src/server/rate-limit.ts
|
|
1332
1359
|
function createRateLimiter(windowMs, max) {
|
|
@@ -1534,6 +1561,81 @@ async function getBackendSignedUrl(config, kind = "image") {
|
|
|
1534
1561
|
if (!res.ok || !data.data) throw new Error(data.error ?? "Failed to create upload URL");
|
|
1535
1562
|
return data.data.url;
|
|
1536
1563
|
}
|
|
1564
|
+
var IDENTITY_PREFIX = "siws_";
|
|
1565
|
+
var ACCOUNT_SESSION_PREFIX = "account_session_";
|
|
1566
|
+
var IDENTITY_DOMAIN = "siws-identity-v1";
|
|
1567
|
+
var ACCOUNT_SESSION_DOMAIN = "account-session-v1";
|
|
1568
|
+
var IDENTITY_TTL_SECONDS = 86400;
|
|
1569
|
+
var ACCOUNT_SESSION_TTL_SECONDS = 30 * 24 * 60 * 60;
|
|
1570
|
+
var CLOCK_SKEW_SECONDS = 60;
|
|
1571
|
+
var encoder = new TextEncoder();
|
|
1572
|
+
var decoder = new TextDecoder();
|
|
1573
|
+
function toHex(bytes) {
|
|
1574
|
+
let out = "";
|
|
1575
|
+
for (const b of bytes) out += b.toString(16).padStart(2, "0");
|
|
1576
|
+
return out;
|
|
1577
|
+
}
|
|
1578
|
+
function sign(secret, domain, payload) {
|
|
1579
|
+
const message = domain === null ? payload : `${domain}.${payload}`;
|
|
1580
|
+
return toHex(hmac_js.hmac(sha2_js.sha256, encoder.encode(secret), encoder.encode(message)));
|
|
1581
|
+
}
|
|
1582
|
+
function constantTimeEquals(a, b) {
|
|
1583
|
+
if (a.length !== b.length) return false;
|
|
1584
|
+
let diff = 0;
|
|
1585
|
+
for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
1586
|
+
return diff === 0;
|
|
1587
|
+
}
|
|
1588
|
+
function signatureMatches(secret, domain, payload, provided) {
|
|
1589
|
+
return constantTimeEquals(provided, sign(secret, domain, payload)) || constantTimeEquals(provided, sign(secret, null, payload));
|
|
1590
|
+
}
|
|
1591
|
+
function encodePayload(value) {
|
|
1592
|
+
return base.base64urlnopad.encode(encoder.encode(JSON.stringify(value)));
|
|
1593
|
+
}
|
|
1594
|
+
function decodePayload(payload) {
|
|
1595
|
+
try {
|
|
1596
|
+
return JSON.parse(decoder.decode(base.base64urlnopad.decode(payload)));
|
|
1597
|
+
} catch {
|
|
1598
|
+
return null;
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
function splitToken(raw, prefix) {
|
|
1602
|
+
if (!raw.startsWith(prefix)) return null;
|
|
1603
|
+
const inner = raw.slice(prefix.length);
|
|
1604
|
+
const dot = inner.lastIndexOf(".");
|
|
1605
|
+
if (dot === -1) return null;
|
|
1606
|
+
return { payload: inner.slice(0, dot), signature: inner.slice(dot + 1) };
|
|
1607
|
+
}
|
|
1608
|
+
function withinLifetime(iat, exp) {
|
|
1609
|
+
if (!iat || !exp) return false;
|
|
1610
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1611
|
+
return exp >= now && iat <= now + CLOCK_SKEW_SECONDS;
|
|
1612
|
+
}
|
|
1613
|
+
function issueSiwsToken(secret, chain, wallet, ttlSeconds = IDENTITY_TTL_SECONDS) {
|
|
1614
|
+
const iat = Math.floor(Date.now() / 1e3);
|
|
1615
|
+
const payload = encodePayload({ sub: wallet, chain, iat, exp: iat + ttlSeconds });
|
|
1616
|
+
return `${IDENTITY_PREFIX}${payload}.${sign(secret, IDENTITY_DOMAIN, payload)}`;
|
|
1617
|
+
}
|
|
1618
|
+
function verifySiwsToken(secret, raw) {
|
|
1619
|
+
const parts = splitToken(raw, IDENTITY_PREFIX);
|
|
1620
|
+
if (!parts) return null;
|
|
1621
|
+
if (!signatureMatches(secret, IDENTITY_DOMAIN, parts.payload, parts.signature)) return null;
|
|
1622
|
+
const data = decodePayload(parts.payload);
|
|
1623
|
+
if (!data?.sub || !withinLifetime(data.iat, data.exp)) return null;
|
|
1624
|
+
return { address: data.sub, chain: data.chain ?? "STARKNET" };
|
|
1625
|
+
}
|
|
1626
|
+
function issueAccountSessionToken(secret, accountId, ttlSeconds = ACCOUNT_SESSION_TTL_SECONDS) {
|
|
1627
|
+
const iat = Math.floor(Date.now() / 1e3);
|
|
1628
|
+
const payload = encodePayload({ accountId, iat, exp: iat + ttlSeconds });
|
|
1629
|
+
return `${ACCOUNT_SESSION_PREFIX}${payload}.${sign(secret, ACCOUNT_SESSION_DOMAIN, payload)}`;
|
|
1630
|
+
}
|
|
1631
|
+
function verifyAccountSessionToken(secret, raw) {
|
|
1632
|
+
const parts = splitToken(raw, ACCOUNT_SESSION_PREFIX);
|
|
1633
|
+
if (!parts) return null;
|
|
1634
|
+
if (!signatureMatches(secret, ACCOUNT_SESSION_DOMAIN, parts.payload, parts.signature)) return null;
|
|
1635
|
+
const data = decodePayload(parts.payload);
|
|
1636
|
+
if (!data?.accountId || !withinLifetime(data.iat, data.exp)) return null;
|
|
1637
|
+
return data.accountId;
|
|
1638
|
+
}
|
|
1537
1639
|
|
|
1538
1640
|
// src/metadata.ts
|
|
1539
1641
|
var RESERVED_TRAITS = /* @__PURE__ */ new Set([
|
|
@@ -1628,18 +1730,22 @@ function resolveSafeImageContentType(contentType) {
|
|
|
1628
1730
|
}
|
|
1629
1731
|
var MAX_IPFS_GATEWAY_RESPONSE_BYTES = 25 * 1024 * 1024;
|
|
1630
1732
|
|
|
1733
|
+
exports.ACCOUNT_SESSION_TTL_SECONDS = ACCOUNT_SESSION_TTL_SECONDS;
|
|
1631
1734
|
exports.ALLOWED_IMAGE_CONTENT_TYPES = ALLOWED_IMAGE_CONTENT_TYPES;
|
|
1632
1735
|
exports.ApiClient = ApiClient;
|
|
1633
1736
|
exports.CHAINS = CHAINS;
|
|
1634
1737
|
exports.DEFAULT_CHAIN = DEFAULT_CHAIN;
|
|
1635
1738
|
exports.DEFAULT_CURRENCY = DEFAULT_CURRENCY;
|
|
1636
1739
|
exports.FeeConfigSchema = FeeConfigSchema;
|
|
1740
|
+
exports.IDENTITY_TTL_SECONDS = IDENTITY_TTL_SECONDS;
|
|
1637
1741
|
exports.IPFS_SAFE_CONTENT_TYPE_PREFIXES = IPFS_SAFE_CONTENT_TYPE_PREFIXES;
|
|
1638
1742
|
exports.MAX_IMAGE_PROXY_BYTES = MAX_IMAGE_PROXY_BYTES;
|
|
1639
1743
|
exports.MAX_IMAGE_REDIRECTS = MAX_IMAGE_REDIRECTS;
|
|
1640
1744
|
exports.MAX_IPFS_GATEWAY_RESPONSE_BYTES = MAX_IPFS_GATEWAY_RESPONSE_BYTES;
|
|
1641
1745
|
exports.MedialaneApiError = MedialaneApiError;
|
|
1642
1746
|
exports.OPEN_LICENSES = OPEN_LICENSES;
|
|
1747
|
+
exports.PAID_UPSTREAM_MARKERS = PAID_UPSTREAM_MARKERS;
|
|
1748
|
+
exports.POLICY_REFUSAL_CODES = POLICY_REFUSAL_CODES;
|
|
1643
1749
|
exports.PUBLIC_RPC_FALLBACKS = PUBLIC_RPC_FALLBACKS;
|
|
1644
1750
|
exports.RESERVED_TRAITS = RESERVED_TRAITS;
|
|
1645
1751
|
exports.STARKNET_COLLECTION_1155_CLASS_HASH = STARKNET_COLLECTION_1155_CLASS_HASH;
|
|
@@ -1700,11 +1806,14 @@ exports.getStarknetCoordinates = getStarknetCoordinates;
|
|
|
1700
1806
|
exports.getTokenByAddress = getTokenByAddress;
|
|
1701
1807
|
exports.getTokenBySymbol = getTokenBySymbol;
|
|
1702
1808
|
exports.hasCapability = hasCapability;
|
|
1809
|
+
exports.isPolicyRefusal = isPolicyRefusal;
|
|
1703
1810
|
exports.isPrivateHost = isPrivateHost;
|
|
1704
1811
|
exports.isSameOrigin = isSameOrigin;
|
|
1705
1812
|
exports.isServiceId = isServiceId;
|
|
1706
1813
|
exports.isTransientRpcError = isTransientRpcError;
|
|
1707
1814
|
exports.isValidIpfsCidPath = isValidIpfsCidPath;
|
|
1815
|
+
exports.issueAccountSessionToken = issueAccountSessionToken;
|
|
1816
|
+
exports.issueSiwsToken = issueSiwsToken;
|
|
1708
1817
|
exports.listServices = listServices;
|
|
1709
1818
|
exports.normalizeAddress = normalizeAddress;
|
|
1710
1819
|
exports.normalizeHash = normalizeHash;
|
|
@@ -1722,5 +1831,7 @@ exports.uploadDirectoryToBackend = uploadDirectoryToBackend;
|
|
|
1722
1831
|
exports.uploadFileToBackend = uploadFileToBackend;
|
|
1723
1832
|
exports.uploadJsonToBackend = uploadJsonToBackend;
|
|
1724
1833
|
exports.validateUrl = validateUrl;
|
|
1834
|
+
exports.verifyAccountSessionToken = verifyAccountSessionToken;
|
|
1835
|
+
exports.verifySiwsToken = verifySiwsToken;
|
|
1725
1836
|
//# sourceMappingURL=index.cjs.map
|
|
1726
1837
|
//# sourceMappingURL=index.cjs.map
|