@medialane/sdk 0.104.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 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
 
@@ -1559,6 +1561,81 @@ async function getBackendSignedUrl(config, kind = "image") {
1559
1561
  if (!res.ok || !data.data) throw new Error(data.error ?? "Failed to create upload URL");
1560
1562
  return data.data.url;
1561
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
+ }
1562
1639
 
1563
1640
  // src/metadata.ts
1564
1641
  var RESERVED_TRAITS = /* @__PURE__ */ new Set([
@@ -1653,12 +1730,14 @@ function resolveSafeImageContentType(contentType) {
1653
1730
  }
1654
1731
  var MAX_IPFS_GATEWAY_RESPONSE_BYTES = 25 * 1024 * 1024;
1655
1732
 
1733
+ exports.ACCOUNT_SESSION_TTL_SECONDS = ACCOUNT_SESSION_TTL_SECONDS;
1656
1734
  exports.ALLOWED_IMAGE_CONTENT_TYPES = ALLOWED_IMAGE_CONTENT_TYPES;
1657
1735
  exports.ApiClient = ApiClient;
1658
1736
  exports.CHAINS = CHAINS;
1659
1737
  exports.DEFAULT_CHAIN = DEFAULT_CHAIN;
1660
1738
  exports.DEFAULT_CURRENCY = DEFAULT_CURRENCY;
1661
1739
  exports.FeeConfigSchema = FeeConfigSchema;
1740
+ exports.IDENTITY_TTL_SECONDS = IDENTITY_TTL_SECONDS;
1662
1741
  exports.IPFS_SAFE_CONTENT_TYPE_PREFIXES = IPFS_SAFE_CONTENT_TYPE_PREFIXES;
1663
1742
  exports.MAX_IMAGE_PROXY_BYTES = MAX_IMAGE_PROXY_BYTES;
1664
1743
  exports.MAX_IMAGE_REDIRECTS = MAX_IMAGE_REDIRECTS;
@@ -1733,6 +1812,8 @@ exports.isSameOrigin = isSameOrigin;
1733
1812
  exports.isServiceId = isServiceId;
1734
1813
  exports.isTransientRpcError = isTransientRpcError;
1735
1814
  exports.isValidIpfsCidPath = isValidIpfsCidPath;
1815
+ exports.issueAccountSessionToken = issueAccountSessionToken;
1816
+ exports.issueSiwsToken = issueSiwsToken;
1736
1817
  exports.listServices = listServices;
1737
1818
  exports.normalizeAddress = normalizeAddress;
1738
1819
  exports.normalizeHash = normalizeHash;
@@ -1750,5 +1831,7 @@ exports.uploadDirectoryToBackend = uploadDirectoryToBackend;
1750
1831
  exports.uploadFileToBackend = uploadFileToBackend;
1751
1832
  exports.uploadJsonToBackend = uploadJsonToBackend;
1752
1833
  exports.validateUrl = validateUrl;
1834
+ exports.verifyAccountSessionToken = verifyAccountSessionToken;
1835
+ exports.verifySiwsToken = verifySiwsToken;
1753
1836
  //# sourceMappingURL=index.cjs.map
1754
1837
  //# sourceMappingURL=index.cjs.map