@unicitylabs/sphere-sdk 0.5.8 → 0.6.0-dev.1
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/core/index.cjs +11 -9
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +0 -10
- package/dist/core/index.d.ts +0 -10
- package/dist/core/index.js +11 -9
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +191 -497
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +191 -497
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +203 -509
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +10 -20
- package/dist/impl/nodejs/index.d.ts +10 -20
- package/dist/impl/nodejs/index.js +203 -509
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +22 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -11
- package/dist/index.d.ts +1 -11
- package/dist/index.js +21 -10
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -717,114 +717,6 @@ var oidNist = (suffix) => ({
|
|
|
717
717
|
oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, suffix])
|
|
718
718
|
});
|
|
719
719
|
|
|
720
|
-
// node_modules/@noble/hashes/hmac.js
|
|
721
|
-
var _HMAC = class {
|
|
722
|
-
oHash;
|
|
723
|
-
iHash;
|
|
724
|
-
blockLen;
|
|
725
|
-
outputLen;
|
|
726
|
-
finished = false;
|
|
727
|
-
destroyed = false;
|
|
728
|
-
constructor(hash, key) {
|
|
729
|
-
ahash(hash);
|
|
730
|
-
abytes(key, void 0, "key");
|
|
731
|
-
this.iHash = hash.create();
|
|
732
|
-
if (typeof this.iHash.update !== "function")
|
|
733
|
-
throw new Error("Expected instance of class which extends utils.Hash");
|
|
734
|
-
this.blockLen = this.iHash.blockLen;
|
|
735
|
-
this.outputLen = this.iHash.outputLen;
|
|
736
|
-
const blockLen = this.blockLen;
|
|
737
|
-
const pad = new Uint8Array(blockLen);
|
|
738
|
-
pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
|
|
739
|
-
for (let i = 0; i < pad.length; i++)
|
|
740
|
-
pad[i] ^= 54;
|
|
741
|
-
this.iHash.update(pad);
|
|
742
|
-
this.oHash = hash.create();
|
|
743
|
-
for (let i = 0; i < pad.length; i++)
|
|
744
|
-
pad[i] ^= 54 ^ 92;
|
|
745
|
-
this.oHash.update(pad);
|
|
746
|
-
clean(pad);
|
|
747
|
-
}
|
|
748
|
-
update(buf) {
|
|
749
|
-
aexists(this);
|
|
750
|
-
this.iHash.update(buf);
|
|
751
|
-
return this;
|
|
752
|
-
}
|
|
753
|
-
digestInto(out) {
|
|
754
|
-
aexists(this);
|
|
755
|
-
abytes(out, this.outputLen, "output");
|
|
756
|
-
this.finished = true;
|
|
757
|
-
this.iHash.digestInto(out);
|
|
758
|
-
this.oHash.update(out);
|
|
759
|
-
this.oHash.digestInto(out);
|
|
760
|
-
this.destroy();
|
|
761
|
-
}
|
|
762
|
-
digest() {
|
|
763
|
-
const out = new Uint8Array(this.oHash.outputLen);
|
|
764
|
-
this.digestInto(out);
|
|
765
|
-
return out;
|
|
766
|
-
}
|
|
767
|
-
_cloneInto(to) {
|
|
768
|
-
to ||= Object.create(Object.getPrototypeOf(this), {});
|
|
769
|
-
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
|
770
|
-
to = to;
|
|
771
|
-
to.finished = finished;
|
|
772
|
-
to.destroyed = destroyed;
|
|
773
|
-
to.blockLen = blockLen;
|
|
774
|
-
to.outputLen = outputLen;
|
|
775
|
-
to.oHash = oHash._cloneInto(to.oHash);
|
|
776
|
-
to.iHash = iHash._cloneInto(to.iHash);
|
|
777
|
-
return to;
|
|
778
|
-
}
|
|
779
|
-
clone() {
|
|
780
|
-
return this._cloneInto();
|
|
781
|
-
}
|
|
782
|
-
destroy() {
|
|
783
|
-
this.destroyed = true;
|
|
784
|
-
this.oHash.destroy();
|
|
785
|
-
this.iHash.destroy();
|
|
786
|
-
}
|
|
787
|
-
};
|
|
788
|
-
var hmac = (hash, key, message) => new _HMAC(hash, key).update(message).digest();
|
|
789
|
-
hmac.create = (hash, key) => new _HMAC(hash, key);
|
|
790
|
-
|
|
791
|
-
// node_modules/@noble/hashes/hkdf.js
|
|
792
|
-
function extract(hash, ikm, salt) {
|
|
793
|
-
ahash(hash);
|
|
794
|
-
if (salt === void 0)
|
|
795
|
-
salt = new Uint8Array(hash.outputLen);
|
|
796
|
-
return hmac(hash, salt, ikm);
|
|
797
|
-
}
|
|
798
|
-
var HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0);
|
|
799
|
-
var EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of();
|
|
800
|
-
function expand(hash, prk, info, length = 32) {
|
|
801
|
-
ahash(hash);
|
|
802
|
-
anumber(length, "length");
|
|
803
|
-
const olen = hash.outputLen;
|
|
804
|
-
if (length > 255 * olen)
|
|
805
|
-
throw new Error("Length must be <= 255*HashLen");
|
|
806
|
-
const blocks = Math.ceil(length / olen);
|
|
807
|
-
if (info === void 0)
|
|
808
|
-
info = EMPTY_BUFFER;
|
|
809
|
-
else
|
|
810
|
-
abytes(info, void 0, "info");
|
|
811
|
-
const okm = new Uint8Array(blocks * olen);
|
|
812
|
-
const HMAC = hmac.create(hash, prk);
|
|
813
|
-
const HMACTmp = HMAC._cloneInto();
|
|
814
|
-
const T = new Uint8Array(HMAC.outputLen);
|
|
815
|
-
for (let counter = 0; counter < blocks; counter++) {
|
|
816
|
-
HKDF_COUNTER[0] = counter + 1;
|
|
817
|
-
HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T).update(info).update(HKDF_COUNTER).digestInto(T);
|
|
818
|
-
okm.set(T, olen * counter);
|
|
819
|
-
HMAC._cloneInto(HMACTmp);
|
|
820
|
-
}
|
|
821
|
-
HMAC.destroy();
|
|
822
|
-
HMACTmp.destroy();
|
|
823
|
-
clean(T, HKDF_COUNTER);
|
|
824
|
-
return okm.slice(0, length);
|
|
825
|
-
}
|
|
826
|
-
var hkdf = (hash, ikm, salt, info, length) => expand(hash, extract(hash, ikm, salt), info, length);
|
|
827
|
-
|
|
828
720
|
// node_modules/@noble/hashes/_md.js
|
|
829
721
|
function Chi(a, b, c) {
|
|
830
722
|
return a & b ^ ~a & c;
|
|
@@ -1091,134 +983,6 @@ var sha256 = /* @__PURE__ */ createHasher(
|
|
|
1091
983
|
// transport/NostrTransportProvider.ts
|
|
1092
984
|
var import_nostr_js_sdk = require("@unicitylabs/nostr-js-sdk");
|
|
1093
985
|
|
|
1094
|
-
// core/crypto.ts
|
|
1095
|
-
var bip39 = __toESM(require("bip39"), 1);
|
|
1096
|
-
var import_crypto_js = __toESM(require("crypto-js"), 1);
|
|
1097
|
-
var import_elliptic = __toESM(require("elliptic"), 1);
|
|
1098
|
-
|
|
1099
|
-
// core/errors.ts
|
|
1100
|
-
var SphereError = class extends Error {
|
|
1101
|
-
code;
|
|
1102
|
-
cause;
|
|
1103
|
-
constructor(message, code, cause) {
|
|
1104
|
-
super(message);
|
|
1105
|
-
this.name = "SphereError";
|
|
1106
|
-
this.code = code;
|
|
1107
|
-
this.cause = cause;
|
|
1108
|
-
}
|
|
1109
|
-
};
|
|
1110
|
-
|
|
1111
|
-
// core/bech32.ts
|
|
1112
|
-
var CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
|
1113
|
-
var GENERATOR = [996825010, 642813549, 513874426, 1027748829, 705979059];
|
|
1114
|
-
function convertBits(data, fromBits, toBits, pad) {
|
|
1115
|
-
let acc = 0;
|
|
1116
|
-
let bits = 0;
|
|
1117
|
-
const ret = [];
|
|
1118
|
-
const maxv = (1 << toBits) - 1;
|
|
1119
|
-
for (let i = 0; i < data.length; i++) {
|
|
1120
|
-
const value = data[i];
|
|
1121
|
-
if (value < 0 || value >> fromBits !== 0) return null;
|
|
1122
|
-
acc = acc << fromBits | value;
|
|
1123
|
-
bits += fromBits;
|
|
1124
|
-
while (bits >= toBits) {
|
|
1125
|
-
bits -= toBits;
|
|
1126
|
-
ret.push(acc >> bits & maxv);
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
if (pad) {
|
|
1130
|
-
if (bits > 0) {
|
|
1131
|
-
ret.push(acc << toBits - bits & maxv);
|
|
1132
|
-
}
|
|
1133
|
-
} else if (bits >= fromBits || acc << toBits - bits & maxv) {
|
|
1134
|
-
return null;
|
|
1135
|
-
}
|
|
1136
|
-
return ret;
|
|
1137
|
-
}
|
|
1138
|
-
function hrpExpand(hrp) {
|
|
1139
|
-
const ret = [];
|
|
1140
|
-
for (let i = 0; i < hrp.length; i++) ret.push(hrp.charCodeAt(i) >> 5);
|
|
1141
|
-
ret.push(0);
|
|
1142
|
-
for (let i = 0; i < hrp.length; i++) ret.push(hrp.charCodeAt(i) & 31);
|
|
1143
|
-
return ret;
|
|
1144
|
-
}
|
|
1145
|
-
function bech32Polymod(values) {
|
|
1146
|
-
let chk = 1;
|
|
1147
|
-
for (let p = 0; p < values.length; p++) {
|
|
1148
|
-
const top = chk >> 25;
|
|
1149
|
-
chk = (chk & 33554431) << 5 ^ values[p];
|
|
1150
|
-
for (let i = 0; i < 5; i++) {
|
|
1151
|
-
if (top >> i & 1) chk ^= GENERATOR[i];
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
return chk;
|
|
1155
|
-
}
|
|
1156
|
-
function bech32Checksum(hrp, data) {
|
|
1157
|
-
const values = hrpExpand(hrp).concat(data).concat([0, 0, 0, 0, 0, 0]);
|
|
1158
|
-
const mod = bech32Polymod(values) ^ 1;
|
|
1159
|
-
const ret = [];
|
|
1160
|
-
for (let p = 0; p < 6; p++) {
|
|
1161
|
-
ret.push(mod >> 5 * (5 - p) & 31);
|
|
1162
|
-
}
|
|
1163
|
-
return ret;
|
|
1164
|
-
}
|
|
1165
|
-
function encodeBech32(hrp, version, program) {
|
|
1166
|
-
if (version < 0 || version > 16) {
|
|
1167
|
-
throw new SphereError("Invalid witness version", "VALIDATION_ERROR");
|
|
1168
|
-
}
|
|
1169
|
-
const converted = convertBits(Array.from(program), 8, 5, true);
|
|
1170
|
-
if (!converted) {
|
|
1171
|
-
throw new SphereError("Failed to convert bits", "VALIDATION_ERROR");
|
|
1172
|
-
}
|
|
1173
|
-
const data = [version].concat(converted);
|
|
1174
|
-
const checksum = bech32Checksum(hrp, data);
|
|
1175
|
-
const combined = data.concat(checksum);
|
|
1176
|
-
let out = hrp + "1";
|
|
1177
|
-
for (let i = 0; i < combined.length; i++) {
|
|
1178
|
-
out += CHARSET[combined[i]];
|
|
1179
|
-
}
|
|
1180
|
-
return out;
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
// core/crypto.ts
|
|
1184
|
-
var ec = new import_elliptic.default.ec("secp256k1");
|
|
1185
|
-
var CURVE_ORDER = BigInt(
|
|
1186
|
-
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"
|
|
1187
|
-
);
|
|
1188
|
-
function getPublicKey(privateKey, compressed = true) {
|
|
1189
|
-
const keyPair = ec.keyFromPrivate(privateKey, "hex");
|
|
1190
|
-
return keyPair.getPublic(compressed, "hex");
|
|
1191
|
-
}
|
|
1192
|
-
function sha2562(data, inputEncoding = "hex") {
|
|
1193
|
-
const parsed = inputEncoding === "hex" ? import_crypto_js.default.enc.Hex.parse(data) : import_crypto_js.default.enc.Utf8.parse(data);
|
|
1194
|
-
return import_crypto_js.default.SHA256(parsed).toString();
|
|
1195
|
-
}
|
|
1196
|
-
function ripemd160(data, inputEncoding = "hex") {
|
|
1197
|
-
const parsed = inputEncoding === "hex" ? import_crypto_js.default.enc.Hex.parse(data) : import_crypto_js.default.enc.Utf8.parse(data);
|
|
1198
|
-
return import_crypto_js.default.RIPEMD160(parsed).toString();
|
|
1199
|
-
}
|
|
1200
|
-
function hash160(data) {
|
|
1201
|
-
const sha = sha2562(data, "hex");
|
|
1202
|
-
return ripemd160(sha, "hex");
|
|
1203
|
-
}
|
|
1204
|
-
function hash160ToBytes(hash160Hex) {
|
|
1205
|
-
const matches = hash160Hex.match(/../g);
|
|
1206
|
-
if (!matches) return new Uint8Array(0);
|
|
1207
|
-
return Uint8Array.from(matches.map((x) => parseInt(x, 16)));
|
|
1208
|
-
}
|
|
1209
|
-
function publicKeyToAddress(publicKey, prefix = "alpha", witnessVersion = 0) {
|
|
1210
|
-
const pubKeyHash = hash160(publicKey);
|
|
1211
|
-
const programBytes = hash160ToBytes(pubKeyHash);
|
|
1212
|
-
return encodeBech32(prefix, witnessVersion, programBytes);
|
|
1213
|
-
}
|
|
1214
|
-
function hexToBytes2(hex) {
|
|
1215
|
-
const matches = hex.match(/../g);
|
|
1216
|
-
if (!matches) {
|
|
1217
|
-
return new Uint8Array(0);
|
|
1218
|
-
}
|
|
1219
|
-
return Uint8Array.from(matches.map((x) => parseInt(x, 16)));
|
|
1220
|
-
}
|
|
1221
|
-
|
|
1222
986
|
// core/logger.ts
|
|
1223
987
|
var LOGGER_KEY = "__sphere_sdk_logger__";
|
|
1224
988
|
function getState() {
|
|
@@ -1311,6 +1075,18 @@ var logger = {
|
|
|
1311
1075
|
}
|
|
1312
1076
|
};
|
|
1313
1077
|
|
|
1078
|
+
// core/errors.ts
|
|
1079
|
+
var SphereError = class extends Error {
|
|
1080
|
+
code;
|
|
1081
|
+
cause;
|
|
1082
|
+
constructor(message, code, cause) {
|
|
1083
|
+
super(message);
|
|
1084
|
+
this.name = "SphereError";
|
|
1085
|
+
this.code = code;
|
|
1086
|
+
this.cause = cause;
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
|
|
1314
1090
|
// transport/websocket.ts
|
|
1315
1091
|
var WebSocketReadyState = {
|
|
1316
1092
|
CONNECTING: 0,
|
|
@@ -1333,63 +1109,6 @@ function defaultUUIDGenerator() {
|
|
|
1333
1109
|
var COMPOSING_INDICATOR_KIND = 25050;
|
|
1334
1110
|
var TIMESTAMP_RANDOMIZATION = 2 * 24 * 60 * 60;
|
|
1335
1111
|
var EVENT_KINDS = NOSTR_EVENT_KINDS;
|
|
1336
|
-
function hashAddressForTag(address) {
|
|
1337
|
-
const bytes = new TextEncoder().encode("unicity:address:" + address);
|
|
1338
|
-
return import_buffer.Buffer.from(sha256(bytes)).toString("hex");
|
|
1339
|
-
}
|
|
1340
|
-
function deriveNametagEncryptionKey(privateKeyHex) {
|
|
1341
|
-
const privateKeyBytes = import_buffer.Buffer.from(privateKeyHex, "hex");
|
|
1342
|
-
const saltInput = new TextEncoder().encode("sphere-nametag-salt");
|
|
1343
|
-
const salt = sha256(saltInput);
|
|
1344
|
-
const info = new TextEncoder().encode("nametag-encryption");
|
|
1345
|
-
return hkdf(sha256, privateKeyBytes, salt, info, 32);
|
|
1346
|
-
}
|
|
1347
|
-
async function encryptNametag(nametag, privateKeyHex) {
|
|
1348
|
-
const key = deriveNametagEncryptionKey(privateKeyHex);
|
|
1349
|
-
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
1350
|
-
const encoder = new TextEncoder();
|
|
1351
|
-
const data = encoder.encode(nametag);
|
|
1352
|
-
const cryptoKey = await crypto.subtle.importKey(
|
|
1353
|
-
"raw",
|
|
1354
|
-
new Uint8Array(key).buffer,
|
|
1355
|
-
{ name: "AES-GCM" },
|
|
1356
|
-
false,
|
|
1357
|
-
["encrypt"]
|
|
1358
|
-
);
|
|
1359
|
-
const encrypted = await crypto.subtle.encrypt(
|
|
1360
|
-
{ name: "AES-GCM", iv: new Uint8Array(iv).buffer },
|
|
1361
|
-
cryptoKey,
|
|
1362
|
-
new Uint8Array(data).buffer
|
|
1363
|
-
);
|
|
1364
|
-
const combined = new Uint8Array(iv.length + encrypted.byteLength);
|
|
1365
|
-
combined.set(iv, 0);
|
|
1366
|
-
combined.set(new Uint8Array(encrypted), iv.length);
|
|
1367
|
-
return import_buffer.Buffer.from(combined).toString("base64");
|
|
1368
|
-
}
|
|
1369
|
-
async function decryptNametag(encryptedBase64, privateKeyHex) {
|
|
1370
|
-
try {
|
|
1371
|
-
const key = deriveNametagEncryptionKey(privateKeyHex);
|
|
1372
|
-
const combined = import_buffer.Buffer.from(encryptedBase64, "base64");
|
|
1373
|
-
const iv = combined.slice(0, 12);
|
|
1374
|
-
const ciphertext = combined.slice(12);
|
|
1375
|
-
const cryptoKey = await crypto.subtle.importKey(
|
|
1376
|
-
"raw",
|
|
1377
|
-
new Uint8Array(key).buffer,
|
|
1378
|
-
{ name: "AES-GCM" },
|
|
1379
|
-
false,
|
|
1380
|
-
["decrypt"]
|
|
1381
|
-
);
|
|
1382
|
-
const decrypted = await crypto.subtle.decrypt(
|
|
1383
|
-
{ name: "AES-GCM", iv: new Uint8Array(iv).buffer },
|
|
1384
|
-
cryptoKey,
|
|
1385
|
-
new Uint8Array(ciphertext).buffer
|
|
1386
|
-
);
|
|
1387
|
-
const decoder = new TextDecoder();
|
|
1388
|
-
return decoder.decode(decrypted);
|
|
1389
|
-
} catch {
|
|
1390
|
-
return null;
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
1112
|
var NostrTransportProvider = class {
|
|
1394
1113
|
id = "nostr";
|
|
1395
1114
|
name = "Nostr Transport";
|
|
@@ -1858,138 +1577,51 @@ var NostrTransportProvider = class {
|
|
|
1858
1577
|
}
|
|
1859
1578
|
async resolveNametag(nametag) {
|
|
1860
1579
|
this.ensureConnected();
|
|
1861
|
-
|
|
1862
|
-
let events = await this.queryEvents({
|
|
1863
|
-
kinds: [EVENT_KINDS.NAMETAG_BINDING],
|
|
1864
|
-
"#t": [hashedNametag],
|
|
1865
|
-
limit: 1
|
|
1866
|
-
});
|
|
1867
|
-
if (events.length === 0) {
|
|
1868
|
-
events = await this.queryEvents({
|
|
1869
|
-
kinds: [EVENT_KINDS.NAMETAG_BINDING],
|
|
1870
|
-
"#d": [hashedNametag],
|
|
1871
|
-
limit: 1
|
|
1872
|
-
});
|
|
1873
|
-
}
|
|
1874
|
-
if (events.length === 0) return null;
|
|
1875
|
-
const bindingEvent = events[0];
|
|
1876
|
-
if (bindingEvent.pubkey) {
|
|
1877
|
-
return bindingEvent.pubkey;
|
|
1878
|
-
}
|
|
1879
|
-
const pubkeyTag = bindingEvent.tags.find((t) => t[0] === "p");
|
|
1880
|
-
if (pubkeyTag?.[1]) return pubkeyTag[1];
|
|
1881
|
-
return null;
|
|
1580
|
+
return this.nostrClient.queryPubkeyByNametag(nametag);
|
|
1882
1581
|
}
|
|
1883
1582
|
async resolveNametagInfo(nametag) {
|
|
1884
1583
|
this.ensureConnected();
|
|
1885
|
-
const
|
|
1886
|
-
|
|
1887
|
-
kinds: [EVENT_KINDS.NAMETAG_BINDING],
|
|
1888
|
-
"#t": [hashedNametag],
|
|
1889
|
-
limit: 1
|
|
1890
|
-
});
|
|
1891
|
-
if (events.length === 0) {
|
|
1892
|
-
events = await this.queryEvents({
|
|
1893
|
-
kinds: [EVENT_KINDS.NAMETAG_BINDING],
|
|
1894
|
-
"#d": [hashedNametag],
|
|
1895
|
-
limit: 1
|
|
1896
|
-
});
|
|
1897
|
-
}
|
|
1898
|
-
if (events.length === 0) {
|
|
1584
|
+
const binding = await this.nostrClient.queryBindingByNametag(nametag);
|
|
1585
|
+
if (!binding) {
|
|
1899
1586
|
logger.debug("Nostr", `resolveNametagInfo: no binding events found for Unicity ID "${nametag}"`);
|
|
1900
1587
|
return null;
|
|
1901
1588
|
}
|
|
1902
|
-
|
|
1903
|
-
try {
|
|
1904
|
-
const content = JSON.parse(bindingEvent.content);
|
|
1905
|
-
const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
|
|
1906
|
-
const proxyAddr = await ProxyAddress.fromNameTag(nametag);
|
|
1907
|
-
const proxyAddress = proxyAddr.toString();
|
|
1908
|
-
if (content.public_key && content.l1_address) {
|
|
1909
|
-
return {
|
|
1910
|
-
nametag,
|
|
1911
|
-
transportPubkey: bindingEvent.pubkey,
|
|
1912
|
-
chainPubkey: content.public_key,
|
|
1913
|
-
l1Address: content.l1_address,
|
|
1914
|
-
directAddress: content.direct_address || "",
|
|
1915
|
-
proxyAddress,
|
|
1916
|
-
timestamp: bindingEvent.created_at * 1e3
|
|
1917
|
-
};
|
|
1918
|
-
}
|
|
1919
|
-
logger.debug("Nostr", "Legacy nametag event without extended fields:", nametag);
|
|
1920
|
-
const pubkeyTag = bindingEvent.tags.find((t) => t[0] === "pubkey");
|
|
1921
|
-
const l1Tag = bindingEvent.tags.find((t) => t[0] === "l1");
|
|
1922
|
-
if (pubkeyTag?.[1] && l1Tag?.[1]) {
|
|
1923
|
-
return {
|
|
1924
|
-
nametag,
|
|
1925
|
-
transportPubkey: bindingEvent.pubkey,
|
|
1926
|
-
chainPubkey: pubkeyTag[1],
|
|
1927
|
-
l1Address: l1Tag[1],
|
|
1928
|
-
directAddress: "",
|
|
1929
|
-
proxyAddress,
|
|
1930
|
-
timestamp: bindingEvent.created_at * 1e3
|
|
1931
|
-
};
|
|
1932
|
-
}
|
|
1933
|
-
return {
|
|
1934
|
-
nametag,
|
|
1935
|
-
transportPubkey: bindingEvent.pubkey,
|
|
1936
|
-
chainPubkey: "",
|
|
1937
|
-
// Cannot derive from 32-byte Nostr pubkey
|
|
1938
|
-
l1Address: "",
|
|
1939
|
-
// Cannot derive without 33-byte pubkey
|
|
1940
|
-
directAddress: "",
|
|
1941
|
-
proxyAddress,
|
|
1942
|
-
timestamp: bindingEvent.created_at * 1e3
|
|
1943
|
-
};
|
|
1944
|
-
} catch {
|
|
1945
|
-
const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
|
|
1946
|
-
const proxyAddr = await ProxyAddress.fromNameTag(nametag);
|
|
1947
|
-
return {
|
|
1948
|
-
nametag,
|
|
1949
|
-
transportPubkey: bindingEvent.pubkey,
|
|
1950
|
-
chainPubkey: "",
|
|
1951
|
-
l1Address: "",
|
|
1952
|
-
directAddress: "",
|
|
1953
|
-
proxyAddress: proxyAddr.toString(),
|
|
1954
|
-
timestamp: bindingEvent.created_at * 1e3
|
|
1955
|
-
};
|
|
1956
|
-
}
|
|
1589
|
+
return this.bindingInfoToPeerInfo(binding, nametag);
|
|
1957
1590
|
}
|
|
1958
1591
|
/**
|
|
1959
1592
|
* Resolve a DIRECT://, PROXY://, or L1 address to full peer info.
|
|
1960
|
-
* Performs reverse lookup
|
|
1961
|
-
* Works with both new identity binding events and legacy nametag binding events.
|
|
1593
|
+
* Performs reverse lookup via nostr-js-sdk with first-seen-wins anti-hijacking.
|
|
1962
1594
|
*/
|
|
1963
1595
|
async resolveAddressInfo(address) {
|
|
1964
1596
|
this.ensureConnected();
|
|
1965
|
-
const
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
};
|
|
1984
|
-
} catch {
|
|
1985
|
-
return {
|
|
1986
|
-
transportPubkey: bindingEvent.pubkey,
|
|
1987
|
-
chainPubkey: "",
|
|
1988
|
-
l1Address: "",
|
|
1989
|
-
directAddress: "",
|
|
1990
|
-
timestamp: bindingEvent.created_at * 1e3
|
|
1991
|
-
};
|
|
1597
|
+
const binding = await this.nostrClient.queryBindingByAddress(address);
|
|
1598
|
+
if (!binding) return null;
|
|
1599
|
+
return this.bindingInfoToPeerInfo(binding);
|
|
1600
|
+
}
|
|
1601
|
+
/**
|
|
1602
|
+
* Convert a BindingInfo (from nostr-js-sdk) to PeerInfo (sphere-sdk type).
|
|
1603
|
+
* Computes PROXY address from nametag if available.
|
|
1604
|
+
*/
|
|
1605
|
+
async bindingInfoToPeerInfo(binding, nametag) {
|
|
1606
|
+
const nametagValue = nametag || binding.nametag;
|
|
1607
|
+
let proxyAddress = binding.proxyAddress;
|
|
1608
|
+
if (nametagValue && !proxyAddress) {
|
|
1609
|
+
try {
|
|
1610
|
+
const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
|
|
1611
|
+
const proxyAddr = await ProxyAddress.fromNameTag(nametagValue);
|
|
1612
|
+
proxyAddress = proxyAddr.toString();
|
|
1613
|
+
} catch {
|
|
1614
|
+
}
|
|
1992
1615
|
}
|
|
1616
|
+
return {
|
|
1617
|
+
nametag: nametagValue,
|
|
1618
|
+
transportPubkey: binding.transportPubkey,
|
|
1619
|
+
chainPubkey: binding.publicKey || "",
|
|
1620
|
+
l1Address: binding.l1Address || "",
|
|
1621
|
+
directAddress: binding.directAddress || "",
|
|
1622
|
+
proxyAddress,
|
|
1623
|
+
timestamp: binding.timestamp
|
|
1624
|
+
};
|
|
1993
1625
|
}
|
|
1994
1626
|
/**
|
|
1995
1627
|
* Resolve transport pubkey (Nostr pubkey) to full peer info.
|
|
@@ -2091,7 +1723,7 @@ var NostrTransportProvider = class {
|
|
|
2091
1723
|
try {
|
|
2092
1724
|
const content = JSON.parse(event.content);
|
|
2093
1725
|
if (content.encrypted_nametag) {
|
|
2094
|
-
const decrypted = await decryptNametag(
|
|
1726
|
+
const decrypted = await (0, import_nostr_js_sdk.decryptNametag)(
|
|
2095
1727
|
content.encrypted_nametag,
|
|
2096
1728
|
this.identity.privateKey
|
|
2097
1729
|
);
|
|
@@ -2109,11 +1741,10 @@ var NostrTransportProvider = class {
|
|
|
2109
1741
|
}
|
|
2110
1742
|
/**
|
|
2111
1743
|
* Publish identity binding event on Nostr.
|
|
2112
|
-
* Without nametag: publishes base binding (chainPubkey, l1Address, directAddress)
|
|
2113
|
-
*
|
|
2114
|
-
*
|
|
2115
|
-
*
|
|
2116
|
-
* Each HD address index has its own Nostr key → its own binding event.
|
|
1744
|
+
* Without nametag: publishes base binding (chainPubkey, l1Address, directAddress)
|
|
1745
|
+
* using a per-identity d-tag for address discovery.
|
|
1746
|
+
* With nametag: delegates to nostr-js-sdk's publishNametagBinding which handles
|
|
1747
|
+
* conflict detection (first-seen-wins), encryption, and indexed tags.
|
|
2117
1748
|
*
|
|
2118
1749
|
* @returns true if successful, false if nametag is taken by another pubkey
|
|
2119
1750
|
*/
|
|
@@ -2123,102 +1754,41 @@ var NostrTransportProvider = class {
|
|
|
2123
1754
|
throw new SphereError("Identity not set", "NOT_INITIALIZED");
|
|
2124
1755
|
}
|
|
2125
1756
|
const nostrPubkey = this.getNostrPubkey();
|
|
2126
|
-
const dTagBytes = new TextEncoder().encode("unicity:identity:" + nostrPubkey);
|
|
2127
|
-
const dTag = import_buffer.Buffer.from(sha256(dTagBytes)).toString("hex");
|
|
2128
|
-
const contentObj = {
|
|
2129
|
-
public_key: chainPubkey,
|
|
2130
|
-
l1_address: l1Address,
|
|
2131
|
-
direct_address: directAddress
|
|
2132
|
-
};
|
|
2133
|
-
const tags = [
|
|
2134
|
-
["d", dTag],
|
|
2135
|
-
["t", hashAddressForTag(chainPubkey)],
|
|
2136
|
-
["t", hashAddressForTag(directAddress)],
|
|
2137
|
-
["t", hashAddressForTag(l1Address)]
|
|
2138
|
-
];
|
|
2139
1757
|
if (nametag) {
|
|
2140
|
-
const existing = await this.resolveNametag(nametag);
|
|
2141
|
-
if (existing && existing !== nostrPubkey) {
|
|
2142
|
-
logger.debug("Nostr", "Unicity ID already taken:", nametag, "- owner:", existing);
|
|
2143
|
-
return false;
|
|
2144
|
-
}
|
|
2145
1758
|
const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
|
|
2146
1759
|
const proxyAddr = await ProxyAddress.fromNameTag(nametag);
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
const hashedNametag = (0, import_nostr_js_sdk.hashNametag)(nametag);
|
|
2170
|
-
const event = await this.createEvent(EVENT_KINDS.NAMETAG_BINDING, address, [
|
|
2171
|
-
["d", hashedNametag],
|
|
2172
|
-
["a", address]
|
|
2173
|
-
]);
|
|
2174
|
-
await this.publishEvent(event);
|
|
2175
|
-
logger.debug("Nostr", "Published Unicity ID binding:", nametag);
|
|
2176
|
-
}
|
|
2177
|
-
async registerNametag(nametag, _publicKey, directAddress = "") {
|
|
2178
|
-
this.ensureReady();
|
|
2179
|
-
if (!this.identity) {
|
|
2180
|
-
throw new SphereError("Identity not set", "NOT_INITIALIZED");
|
|
2181
|
-
}
|
|
2182
|
-
const nostrPubkey = this.getNostrPubkey();
|
|
2183
|
-
const existing = await this.resolveNametag(nametag);
|
|
2184
|
-
logger.debug("Nostr", "registerNametag:", nametag, "existing:", existing, "myPubkey:", nostrPubkey);
|
|
2185
|
-
if (existing && existing !== nostrPubkey) {
|
|
2186
|
-
logger.debug("Nostr", "Unicity ID already taken:", nametag, "- owner:", existing);
|
|
2187
|
-
return false;
|
|
1760
|
+
try {
|
|
1761
|
+
const success2 = await this.nostrClient.publishNametagBinding(
|
|
1762
|
+
nametag,
|
|
1763
|
+
nostrPubkey,
|
|
1764
|
+
{
|
|
1765
|
+
publicKey: chainPubkey,
|
|
1766
|
+
l1Address,
|
|
1767
|
+
directAddress,
|
|
1768
|
+
proxyAddress: proxyAddr.toString()
|
|
1769
|
+
}
|
|
1770
|
+
);
|
|
1771
|
+
if (success2) {
|
|
1772
|
+
logger.debug("Nostr", "Published identity binding with Unicity ID:", nametag, "for pubkey:", nostrPubkey.slice(0, 16) + "...");
|
|
1773
|
+
}
|
|
1774
|
+
return success2;
|
|
1775
|
+
} catch (error) {
|
|
1776
|
+
if (error instanceof Error && error.message.includes("already claimed")) {
|
|
1777
|
+
logger.debug("Nostr", "Unicity ID already taken:", nametag);
|
|
1778
|
+
return false;
|
|
1779
|
+
}
|
|
1780
|
+
throw error;
|
|
1781
|
+
}
|
|
2188
1782
|
}
|
|
2189
|
-
const
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
|
|
2194
|
-
const proxyAddr = await ProxyAddress.fromNameTag(nametag);
|
|
2195
|
-
const proxyAddress = proxyAddr.toString();
|
|
2196
|
-
const hashedNametag = (0, import_nostr_js_sdk.hashNametag)(nametag);
|
|
2197
|
-
const content = JSON.stringify({
|
|
2198
|
-
nametag_hash: hashedNametag,
|
|
2199
|
-
address: nostrPubkey,
|
|
2200
|
-
verified: Date.now(),
|
|
2201
|
-
// Extended fields for nametag recovery and address lookup
|
|
2202
|
-
encrypted_nametag: encryptedNametag,
|
|
2203
|
-
public_key: compressedPubkey,
|
|
2204
|
-
l1_address: l1Address,
|
|
2205
|
-
direct_address: directAddress,
|
|
2206
|
-
proxy_address: proxyAddress
|
|
1783
|
+
const success = await this.nostrClient.publishIdentityBinding({
|
|
1784
|
+
publicKey: chainPubkey,
|
|
1785
|
+
l1Address,
|
|
1786
|
+
directAddress
|
|
2207
1787
|
});
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
["t", hashAddressForTag(directAddress)],
|
|
2213
|
-
["t", hashAddressForTag(proxyAddress)],
|
|
2214
|
-
["address", nostrPubkey],
|
|
2215
|
-
["pubkey", compressedPubkey],
|
|
2216
|
-
["l1", l1Address]
|
|
2217
|
-
];
|
|
2218
|
-
const event = await this.createEvent(EVENT_KINDS.NAMETAG_BINDING, content, tags);
|
|
2219
|
-
await this.publishEvent(event);
|
|
2220
|
-
logger.debug("Nostr", "Registered Unicity ID:", nametag, "for pubkey:", nostrPubkey.slice(0, 16) + "...", "l1:", l1Address.slice(0, 12) + "...");
|
|
2221
|
-
return true;
|
|
1788
|
+
if (success) {
|
|
1789
|
+
logger.debug("Nostr", "Published identity binding (no Unicity ID) for pubkey:", nostrPubkey.slice(0, 16) + "...");
|
|
1790
|
+
}
|
|
1791
|
+
return success;
|
|
2222
1792
|
}
|
|
2223
1793
|
// Track broadcast subscriptions
|
|
2224
1794
|
broadcastSubscriptions = /* @__PURE__ */ new Map();
|
|
@@ -3447,6 +3017,130 @@ var InMemoryIpfsStatePersistence = class {
|
|
|
3447
3017
|
}
|
|
3448
3018
|
};
|
|
3449
3019
|
|
|
3020
|
+
// node_modules/@noble/hashes/hmac.js
|
|
3021
|
+
var _HMAC = class {
|
|
3022
|
+
oHash;
|
|
3023
|
+
iHash;
|
|
3024
|
+
blockLen;
|
|
3025
|
+
outputLen;
|
|
3026
|
+
finished = false;
|
|
3027
|
+
destroyed = false;
|
|
3028
|
+
constructor(hash, key) {
|
|
3029
|
+
ahash(hash);
|
|
3030
|
+
abytes(key, void 0, "key");
|
|
3031
|
+
this.iHash = hash.create();
|
|
3032
|
+
if (typeof this.iHash.update !== "function")
|
|
3033
|
+
throw new Error("Expected instance of class which extends utils.Hash");
|
|
3034
|
+
this.blockLen = this.iHash.blockLen;
|
|
3035
|
+
this.outputLen = this.iHash.outputLen;
|
|
3036
|
+
const blockLen = this.blockLen;
|
|
3037
|
+
const pad = new Uint8Array(blockLen);
|
|
3038
|
+
pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
|
|
3039
|
+
for (let i = 0; i < pad.length; i++)
|
|
3040
|
+
pad[i] ^= 54;
|
|
3041
|
+
this.iHash.update(pad);
|
|
3042
|
+
this.oHash = hash.create();
|
|
3043
|
+
for (let i = 0; i < pad.length; i++)
|
|
3044
|
+
pad[i] ^= 54 ^ 92;
|
|
3045
|
+
this.oHash.update(pad);
|
|
3046
|
+
clean(pad);
|
|
3047
|
+
}
|
|
3048
|
+
update(buf) {
|
|
3049
|
+
aexists(this);
|
|
3050
|
+
this.iHash.update(buf);
|
|
3051
|
+
return this;
|
|
3052
|
+
}
|
|
3053
|
+
digestInto(out) {
|
|
3054
|
+
aexists(this);
|
|
3055
|
+
abytes(out, this.outputLen, "output");
|
|
3056
|
+
this.finished = true;
|
|
3057
|
+
this.iHash.digestInto(out);
|
|
3058
|
+
this.oHash.update(out);
|
|
3059
|
+
this.oHash.digestInto(out);
|
|
3060
|
+
this.destroy();
|
|
3061
|
+
}
|
|
3062
|
+
digest() {
|
|
3063
|
+
const out = new Uint8Array(this.oHash.outputLen);
|
|
3064
|
+
this.digestInto(out);
|
|
3065
|
+
return out;
|
|
3066
|
+
}
|
|
3067
|
+
_cloneInto(to) {
|
|
3068
|
+
to ||= Object.create(Object.getPrototypeOf(this), {});
|
|
3069
|
+
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
|
3070
|
+
to = to;
|
|
3071
|
+
to.finished = finished;
|
|
3072
|
+
to.destroyed = destroyed;
|
|
3073
|
+
to.blockLen = blockLen;
|
|
3074
|
+
to.outputLen = outputLen;
|
|
3075
|
+
to.oHash = oHash._cloneInto(to.oHash);
|
|
3076
|
+
to.iHash = iHash._cloneInto(to.iHash);
|
|
3077
|
+
return to;
|
|
3078
|
+
}
|
|
3079
|
+
clone() {
|
|
3080
|
+
return this._cloneInto();
|
|
3081
|
+
}
|
|
3082
|
+
destroy() {
|
|
3083
|
+
this.destroyed = true;
|
|
3084
|
+
this.oHash.destroy();
|
|
3085
|
+
this.iHash.destroy();
|
|
3086
|
+
}
|
|
3087
|
+
};
|
|
3088
|
+
var hmac = (hash, key, message) => new _HMAC(hash, key).update(message).digest();
|
|
3089
|
+
hmac.create = (hash, key) => new _HMAC(hash, key);
|
|
3090
|
+
|
|
3091
|
+
// node_modules/@noble/hashes/hkdf.js
|
|
3092
|
+
function extract(hash, ikm, salt) {
|
|
3093
|
+
ahash(hash);
|
|
3094
|
+
if (salt === void 0)
|
|
3095
|
+
salt = new Uint8Array(hash.outputLen);
|
|
3096
|
+
return hmac(hash, salt, ikm);
|
|
3097
|
+
}
|
|
3098
|
+
var HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0);
|
|
3099
|
+
var EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of();
|
|
3100
|
+
function expand(hash, prk, info, length = 32) {
|
|
3101
|
+
ahash(hash);
|
|
3102
|
+
anumber(length, "length");
|
|
3103
|
+
const olen = hash.outputLen;
|
|
3104
|
+
if (length > 255 * olen)
|
|
3105
|
+
throw new Error("Length must be <= 255*HashLen");
|
|
3106
|
+
const blocks = Math.ceil(length / olen);
|
|
3107
|
+
if (info === void 0)
|
|
3108
|
+
info = EMPTY_BUFFER;
|
|
3109
|
+
else
|
|
3110
|
+
abytes(info, void 0, "info");
|
|
3111
|
+
const okm = new Uint8Array(blocks * olen);
|
|
3112
|
+
const HMAC = hmac.create(hash, prk);
|
|
3113
|
+
const HMACTmp = HMAC._cloneInto();
|
|
3114
|
+
const T = new Uint8Array(HMAC.outputLen);
|
|
3115
|
+
for (let counter = 0; counter < blocks; counter++) {
|
|
3116
|
+
HKDF_COUNTER[0] = counter + 1;
|
|
3117
|
+
HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T).update(info).update(HKDF_COUNTER).digestInto(T);
|
|
3118
|
+
okm.set(T, olen * counter);
|
|
3119
|
+
HMAC._cloneInto(HMACTmp);
|
|
3120
|
+
}
|
|
3121
|
+
HMAC.destroy();
|
|
3122
|
+
HMACTmp.destroy();
|
|
3123
|
+
clean(T, HKDF_COUNTER);
|
|
3124
|
+
return okm.slice(0, length);
|
|
3125
|
+
}
|
|
3126
|
+
var hkdf = (hash, ikm, salt, info, length) => expand(hash, extract(hash, ikm, salt), info, length);
|
|
3127
|
+
|
|
3128
|
+
// core/crypto.ts
|
|
3129
|
+
var bip39 = __toESM(require("bip39"), 1);
|
|
3130
|
+
var import_crypto_js = __toESM(require("crypto-js"), 1);
|
|
3131
|
+
var import_elliptic = __toESM(require("elliptic"), 1);
|
|
3132
|
+
var ec = new import_elliptic.default.ec("secp256k1");
|
|
3133
|
+
var CURVE_ORDER = BigInt(
|
|
3134
|
+
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"
|
|
3135
|
+
);
|
|
3136
|
+
function hexToBytes2(hex) {
|
|
3137
|
+
const matches = hex.match(/../g);
|
|
3138
|
+
if (!matches) {
|
|
3139
|
+
return new Uint8Array(0);
|
|
3140
|
+
}
|
|
3141
|
+
return Uint8Array.from(matches.map((x) => parseInt(x, 16)));
|
|
3142
|
+
}
|
|
3143
|
+
|
|
3450
3144
|
// impl/shared/ipfs/ipns-key-derivation.ts
|
|
3451
3145
|
var IPNS_HKDF_INFO = "ipfs-storage-ed25519-v1";
|
|
3452
3146
|
var libp2pCryptoModule = null;
|