@unicitylabs/sphere-sdk 0.1.3 → 0.1.4
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 +54 -15
- package/dist/core/index.cjs +298 -72
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +300 -204
- package/dist/core/index.d.ts +300 -204
- package/dist/core/index.js +298 -72
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +1089 -219
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +1086 -222
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/browser/ipfs.cjs +443 -4
- package/dist/impl/browser/ipfs.cjs.map +1 -1
- package/dist/impl/browser/ipfs.js +442 -3
- package/dist/impl/browser/ipfs.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +1078 -222
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +131 -55
- package/dist/impl/nodejs/index.d.ts +131 -55
- package/dist/impl/nodejs/index.js +1085 -225
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +298 -72
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +608 -286
- package/dist/index.d.ts +608 -286
- package/dist/index.js +298 -72
- package/dist/index.js.map +1 -1
- package/package.json +6 -1
package/dist/core/index.cjs
CHANGED
|
@@ -1445,6 +1445,7 @@ var L1PaymentsModule = class {
|
|
|
1445
1445
|
_chainCode;
|
|
1446
1446
|
_addresses = [];
|
|
1447
1447
|
_wallet;
|
|
1448
|
+
_transport;
|
|
1448
1449
|
constructor(config) {
|
|
1449
1450
|
this._config = {
|
|
1450
1451
|
electrumUrl: config?.electrumUrl ?? "wss://fulcrum.alpha.unicity.network:50004",
|
|
@@ -1457,13 +1458,14 @@ var L1PaymentsModule = class {
|
|
|
1457
1458
|
this._identity = deps.identity;
|
|
1458
1459
|
this._chainCode = deps.chainCode;
|
|
1459
1460
|
this._addresses = deps.addresses ?? [];
|
|
1461
|
+
this._transport = deps.transport;
|
|
1460
1462
|
this._wallet = {
|
|
1461
1463
|
masterPrivateKey: deps.identity.privateKey,
|
|
1462
1464
|
chainCode: deps.chainCode,
|
|
1463
1465
|
addresses: [
|
|
1464
1466
|
{
|
|
1465
|
-
address: deps.identity.
|
|
1466
|
-
publicKey: deps.identity.
|
|
1467
|
+
address: deps.identity.l1Address,
|
|
1468
|
+
publicKey: deps.identity.chainPubkey,
|
|
1467
1469
|
privateKey: deps.identity.privateKey,
|
|
1468
1470
|
path: "m/0",
|
|
1469
1471
|
index: 0
|
|
@@ -1471,7 +1473,7 @@ var L1PaymentsModule = class {
|
|
|
1471
1473
|
]
|
|
1472
1474
|
};
|
|
1473
1475
|
for (const addr of this._addresses) {
|
|
1474
|
-
if (addr !== deps.identity.
|
|
1476
|
+
if (addr !== deps.identity.l1Address) {
|
|
1475
1477
|
this._wallet.addresses.push({
|
|
1476
1478
|
address: addr,
|
|
1477
1479
|
path: null,
|
|
@@ -1494,18 +1496,64 @@ var L1PaymentsModule = class {
|
|
|
1494
1496
|
this._addresses = [];
|
|
1495
1497
|
this._wallet = void 0;
|
|
1496
1498
|
}
|
|
1499
|
+
/**
|
|
1500
|
+
* Check if a string looks like an L1 address (alpha1... or alphat1...)
|
|
1501
|
+
*/
|
|
1502
|
+
isL1Address(value) {
|
|
1503
|
+
return value.startsWith("alpha1") || value.startsWith("alphat1");
|
|
1504
|
+
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Resolve recipient to L1 address
|
|
1507
|
+
* Supports: L1 address (alpha1...), nametag (with or without @)
|
|
1508
|
+
*/
|
|
1509
|
+
async resolveL1Address(recipient) {
|
|
1510
|
+
if (recipient.startsWith("@")) {
|
|
1511
|
+
const nametag = recipient.slice(1);
|
|
1512
|
+
return this.resolveNametagToL1Address(nametag);
|
|
1513
|
+
}
|
|
1514
|
+
if (this.isL1Address(recipient)) {
|
|
1515
|
+
return recipient;
|
|
1516
|
+
}
|
|
1517
|
+
try {
|
|
1518
|
+
const l1Address = await this.resolveNametagToL1Address(recipient);
|
|
1519
|
+
return l1Address;
|
|
1520
|
+
} catch {
|
|
1521
|
+
throw new Error(
|
|
1522
|
+
`Recipient "${recipient}" is not a valid nametag or L1 address. Use @nametag for explicit nametag or a valid alpha1... address.`
|
|
1523
|
+
);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
/**
|
|
1527
|
+
* Resolve nametag to L1 address using transport provider
|
|
1528
|
+
*/
|
|
1529
|
+
async resolveNametagToL1Address(nametag) {
|
|
1530
|
+
if (!this._transport?.resolveNametagInfo) {
|
|
1531
|
+
throw new Error("Transport provider does not support nametag resolution");
|
|
1532
|
+
}
|
|
1533
|
+
const info = await this._transport.resolveNametagInfo(nametag);
|
|
1534
|
+
if (!info) {
|
|
1535
|
+
throw new Error(`Nametag not found: ${nametag}`);
|
|
1536
|
+
}
|
|
1537
|
+
if (!info.l1Address) {
|
|
1538
|
+
throw new Error(
|
|
1539
|
+
`Nametag @${nametag} does not have L1 address information. The owner needs to update their nametag registration.`
|
|
1540
|
+
);
|
|
1541
|
+
}
|
|
1542
|
+
return info.l1Address;
|
|
1543
|
+
}
|
|
1497
1544
|
async send(request) {
|
|
1498
1545
|
this.ensureInitialized();
|
|
1499
1546
|
if (!this._wallet || !this._identity) {
|
|
1500
1547
|
return { success: false, error: "No wallet available" };
|
|
1501
1548
|
}
|
|
1502
1549
|
try {
|
|
1550
|
+
const recipientAddress = await this.resolveL1Address(request.to);
|
|
1503
1551
|
const amountAlpha = parseInt(request.amount, 10) / 1e8;
|
|
1504
1552
|
const results = await sendAlpha(
|
|
1505
1553
|
this._wallet,
|
|
1506
|
-
|
|
1554
|
+
recipientAddress,
|
|
1507
1555
|
amountAlpha,
|
|
1508
|
-
this._identity.
|
|
1556
|
+
this._identity.l1Address
|
|
1509
1557
|
);
|
|
1510
1558
|
if (results && results.length > 0) {
|
|
1511
1559
|
const txids = results.map((r) => r.txid);
|
|
@@ -1727,8 +1775,8 @@ var L1PaymentsModule = class {
|
|
|
1727
1775
|
}
|
|
1728
1776
|
_getWatchedAddresses() {
|
|
1729
1777
|
const addresses = [...this._addresses];
|
|
1730
|
-
if (this._identity?.
|
|
1731
|
-
addresses.unshift(this._identity.
|
|
1778
|
+
if (this._identity?.l1Address && !addresses.includes(this._identity.l1Address)) {
|
|
1779
|
+
addresses.unshift(this._identity.l1Address);
|
|
1732
1780
|
}
|
|
1733
1781
|
return addresses;
|
|
1734
1782
|
}
|
|
@@ -2570,12 +2618,10 @@ function getCurrentStateHash(txf) {
|
|
|
2570
2618
|
|
|
2571
2619
|
// modules/payments/PaymentsModule.ts
|
|
2572
2620
|
var import_Token4 = require("@unicitylabs/state-transition-sdk/lib/token/Token");
|
|
2573
|
-
var import_TokenId3 = require("@unicitylabs/state-transition-sdk/lib/token/TokenId");
|
|
2574
2621
|
var import_CoinId3 = require("@unicitylabs/state-transition-sdk/lib/token/fungible/CoinId");
|
|
2575
2622
|
var import_TransferCommitment2 = require("@unicitylabs/state-transition-sdk/lib/transaction/TransferCommitment");
|
|
2576
2623
|
var import_TransferTransaction = require("@unicitylabs/state-transition-sdk/lib/transaction/TransferTransaction");
|
|
2577
2624
|
var import_SigningService = require("@unicitylabs/state-transition-sdk/lib/sign/SigningService");
|
|
2578
|
-
var import_ProxyAddress = require("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
|
|
2579
2625
|
var import_AddressScheme = require("@unicitylabs/state-transition-sdk/lib/address/AddressScheme");
|
|
2580
2626
|
var import_UnmaskedPredicate3 = require("@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicate");
|
|
2581
2627
|
var import_TokenState3 = require("@unicitylabs/state-transition-sdk/lib/token/TokenState");
|
|
@@ -2866,7 +2912,8 @@ var PaymentsModule = class {
|
|
|
2866
2912
|
this.l1.initialize({
|
|
2867
2913
|
identity: deps.identity,
|
|
2868
2914
|
chainCode: deps.chainCode,
|
|
2869
|
-
addresses: deps.l1Addresses
|
|
2915
|
+
addresses: deps.l1Addresses,
|
|
2916
|
+
transport: deps.transport
|
|
2870
2917
|
});
|
|
2871
2918
|
}
|
|
2872
2919
|
this.unsubscribeTransfers = deps.transport.onTokenTransfer((transfer) => {
|
|
@@ -3263,7 +3310,7 @@ var PaymentsModule = class {
|
|
|
3263
3310
|
}
|
|
3264
3311
|
const request = {
|
|
3265
3312
|
id: transportRequest.id,
|
|
3266
|
-
senderPubkey: transportRequest.
|
|
3313
|
+
senderPubkey: transportRequest.senderTransportPubkey,
|
|
3267
3314
|
amount: transportRequest.request.amount,
|
|
3268
3315
|
coinId: transportRequest.request.coinId,
|
|
3269
3316
|
symbol: transportRequest.request.coinId,
|
|
@@ -3375,7 +3422,7 @@ var PaymentsModule = class {
|
|
|
3375
3422
|
}
|
|
3376
3423
|
const response = {
|
|
3377
3424
|
id: transportResponse.id,
|
|
3378
|
-
responderPubkey: transportResponse.
|
|
3425
|
+
responderPubkey: transportResponse.responderTransportPubkey,
|
|
3379
3426
|
requestId: transportResponse.response.requestId,
|
|
3380
3427
|
responseType: transportResponse.response.responseType,
|
|
3381
3428
|
message: transportResponse.response.message,
|
|
@@ -4129,6 +4176,23 @@ var PaymentsModule = class {
|
|
|
4129
4176
|
// ===========================================================================
|
|
4130
4177
|
// Private: Transfer Operations
|
|
4131
4178
|
// ===========================================================================
|
|
4179
|
+
/**
|
|
4180
|
+
* Detect if a string is an L3 address (not a nametag)
|
|
4181
|
+
* Returns true for: hex pubkeys (64+ chars), PROXY:, DIRECT: prefixed addresses
|
|
4182
|
+
*/
|
|
4183
|
+
isL3Address(value) {
|
|
4184
|
+
if (value.startsWith("PROXY:") || value.startsWith("DIRECT:")) {
|
|
4185
|
+
return true;
|
|
4186
|
+
}
|
|
4187
|
+
if (value.length >= 64 && /^[0-9a-fA-F]+$/.test(value)) {
|
|
4188
|
+
return true;
|
|
4189
|
+
}
|
|
4190
|
+
return false;
|
|
4191
|
+
}
|
|
4192
|
+
/**
|
|
4193
|
+
* Resolve recipient to Nostr pubkey for messaging
|
|
4194
|
+
* Supports: nametag (with or without @), hex pubkey
|
|
4195
|
+
*/
|
|
4132
4196
|
async resolveRecipient(recipient) {
|
|
4133
4197
|
if (recipient.startsWith("@")) {
|
|
4134
4198
|
const nametag = recipient.slice(1);
|
|
@@ -4138,7 +4202,19 @@ var PaymentsModule = class {
|
|
|
4138
4202
|
}
|
|
4139
4203
|
return pubkey;
|
|
4140
4204
|
}
|
|
4141
|
-
|
|
4205
|
+
if (this.isL3Address(recipient)) {
|
|
4206
|
+
return recipient;
|
|
4207
|
+
}
|
|
4208
|
+
if (this.deps?.transport.resolveNametag) {
|
|
4209
|
+
const pubkey = await this.deps.transport.resolveNametag(recipient);
|
|
4210
|
+
if (pubkey) {
|
|
4211
|
+
this.log(`Resolved "${recipient}" as nametag to pubkey`);
|
|
4212
|
+
return pubkey;
|
|
4213
|
+
}
|
|
4214
|
+
}
|
|
4215
|
+
throw new Error(
|
|
4216
|
+
`Recipient "${recipient}" is not a valid nametag or address. Use @nametag for explicit nametag or a valid hex pubkey/PROXY:/DIRECT: address.`
|
|
4217
|
+
);
|
|
4142
4218
|
}
|
|
4143
4219
|
/**
|
|
4144
4220
|
* Create SDK TransferCommitment for a token transfer
|
|
@@ -4170,19 +4246,74 @@ var PaymentsModule = class {
|
|
|
4170
4246
|
return import_SigningService.SigningService.createFromSecret(privateKeyBytes);
|
|
4171
4247
|
}
|
|
4172
4248
|
/**
|
|
4173
|
-
*
|
|
4249
|
+
* Create DirectAddress from a public key using UnmaskedPredicateReference
|
|
4250
|
+
*/
|
|
4251
|
+
async createDirectAddressFromPubkey(pubkeyHex) {
|
|
4252
|
+
const { UnmaskedPredicateReference: UnmaskedPredicateReference3 } = await import("@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicateReference");
|
|
4253
|
+
const { TokenType: TokenType3 } = await import("@unicitylabs/state-transition-sdk/lib/token/TokenType");
|
|
4254
|
+
const UNICITY_TOKEN_TYPE_HEX3 = "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509";
|
|
4255
|
+
const tokenType = new TokenType3(Buffer.from(UNICITY_TOKEN_TYPE_HEX3, "hex"));
|
|
4256
|
+
const pubkeyBytes = new Uint8Array(
|
|
4257
|
+
pubkeyHex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))
|
|
4258
|
+
);
|
|
4259
|
+
const addressRef = await UnmaskedPredicateReference3.create(
|
|
4260
|
+
tokenType,
|
|
4261
|
+
"secp256k1",
|
|
4262
|
+
pubkeyBytes,
|
|
4263
|
+
import_HashAlgorithm3.HashAlgorithm.SHA256
|
|
4264
|
+
);
|
|
4265
|
+
return addressRef.toAddress();
|
|
4266
|
+
}
|
|
4267
|
+
/**
|
|
4268
|
+
* Resolve nametag to 33-byte compressed public key using resolveNametagInfo
|
|
4269
|
+
* Returns null if nametag not found or publicKey not available
|
|
4270
|
+
*/
|
|
4271
|
+
async resolveNametagToPublicKey(nametag) {
|
|
4272
|
+
if (!this.deps?.transport.resolveNametagInfo) {
|
|
4273
|
+
this.log("resolveNametagInfo not available on transport");
|
|
4274
|
+
return null;
|
|
4275
|
+
}
|
|
4276
|
+
const info = await this.deps.transport.resolveNametagInfo(nametag);
|
|
4277
|
+
if (!info) {
|
|
4278
|
+
this.log(`Nametag "${nametag}" not found`);
|
|
4279
|
+
return null;
|
|
4280
|
+
}
|
|
4281
|
+
if (!info.chainPubkey) {
|
|
4282
|
+
this.log(`Nametag "${nametag}" has no 33-byte chainPubkey (legacy event)`);
|
|
4283
|
+
return null;
|
|
4284
|
+
}
|
|
4285
|
+
return info.chainPubkey;
|
|
4286
|
+
}
|
|
4287
|
+
/**
|
|
4288
|
+
* Resolve recipient to IAddress for L3 transfers
|
|
4289
|
+
* Supports: nametag (with or without @), PROXY:, DIRECT:, hex pubkey
|
|
4174
4290
|
*/
|
|
4175
4291
|
async resolveRecipientAddress(recipient) {
|
|
4292
|
+
const { AddressFactory } = await import("@unicitylabs/state-transition-sdk/lib/address/AddressFactory");
|
|
4176
4293
|
if (recipient.startsWith("@")) {
|
|
4177
4294
|
const nametag = recipient.slice(1);
|
|
4178
|
-
const
|
|
4179
|
-
|
|
4295
|
+
const publicKey2 = await this.resolveNametagToPublicKey(nametag);
|
|
4296
|
+
if (publicKey2) {
|
|
4297
|
+
this.log(`Resolved @${nametag} to 33-byte publicKey for DirectAddress`);
|
|
4298
|
+
return this.createDirectAddressFromPubkey(publicKey2);
|
|
4299
|
+
}
|
|
4300
|
+
throw new Error(`Nametag "${nametag}" not found or missing publicKey`);
|
|
4180
4301
|
}
|
|
4181
|
-
|
|
4182
|
-
|
|
4302
|
+
if (recipient.startsWith("PROXY:") || recipient.startsWith("DIRECT:")) {
|
|
4303
|
+
return AddressFactory.createAddress(recipient);
|
|
4304
|
+
}
|
|
4305
|
+
if (recipient.length === 66 && /^[0-9a-fA-F]+$/.test(recipient)) {
|
|
4306
|
+
this.log(`Creating DirectAddress from 33-byte compressed pubkey`);
|
|
4307
|
+
return this.createDirectAddressFromPubkey(recipient);
|
|
4308
|
+
}
|
|
4309
|
+
const publicKey = await this.resolveNametagToPublicKey(recipient);
|
|
4310
|
+
if (publicKey) {
|
|
4311
|
+
this.log(`Resolved "${recipient}" as nametag to 33-byte publicKey for DirectAddress`);
|
|
4312
|
+
return this.createDirectAddressFromPubkey(publicKey);
|
|
4313
|
+
}
|
|
4314
|
+
throw new Error(
|
|
4315
|
+
`Recipient "${recipient}" is not a valid nametag or L3 address. Use @nametag for explicit nametag or a valid 33-byte hex pubkey/PROXY:/DIRECT: address.`
|
|
4183
4316
|
);
|
|
4184
|
-
const tokenId = new import_TokenId3.TokenId(pubkeyBytes.slice(0, 32));
|
|
4185
|
-
return import_ProxyAddress.ProxyAddress.fromTokenId(tokenId);
|
|
4186
4317
|
}
|
|
4187
4318
|
async handleIncomingTransfer(transfer) {
|
|
4188
4319
|
try {
|
|
@@ -4240,7 +4371,39 @@ var PaymentsModule = class {
|
|
|
4240
4371
|
}
|
|
4241
4372
|
}
|
|
4242
4373
|
} else {
|
|
4243
|
-
|
|
4374
|
+
this.log("Finalizing DIRECT address transfer for state tracking...");
|
|
4375
|
+
try {
|
|
4376
|
+
const signingService = await this.createSigningService();
|
|
4377
|
+
const transferSalt = transferTx.data.salt;
|
|
4378
|
+
const recipientPredicate = await import_UnmaskedPredicate3.UnmaskedPredicate.create(
|
|
4379
|
+
sourceToken.id,
|
|
4380
|
+
sourceToken.type,
|
|
4381
|
+
signingService,
|
|
4382
|
+
import_HashAlgorithm3.HashAlgorithm.SHA256,
|
|
4383
|
+
transferSalt
|
|
4384
|
+
);
|
|
4385
|
+
const recipientState = new import_TokenState3.TokenState(recipientPredicate, null);
|
|
4386
|
+
const stClient = this.deps.oracle.getStateTransitionClient?.();
|
|
4387
|
+
const trustBase = this.deps.oracle.getTrustBase?.();
|
|
4388
|
+
if (!stClient || !trustBase) {
|
|
4389
|
+
this.log("Cannot finalize DIRECT transfer - missing client, using source token");
|
|
4390
|
+
tokenData = sourceTokenInput;
|
|
4391
|
+
} else {
|
|
4392
|
+
finalizedSdkToken = await stClient.finalizeTransaction(
|
|
4393
|
+
trustBase,
|
|
4394
|
+
sourceToken,
|
|
4395
|
+
recipientState,
|
|
4396
|
+
transferTx,
|
|
4397
|
+
[]
|
|
4398
|
+
// No nametag tokens needed for DIRECT
|
|
4399
|
+
);
|
|
4400
|
+
tokenData = finalizedSdkToken.toJSON();
|
|
4401
|
+
this.log("DIRECT transfer finalized successfully");
|
|
4402
|
+
}
|
|
4403
|
+
} catch (finalizeError) {
|
|
4404
|
+
this.log("DIRECT finalization failed, using source token:", finalizeError);
|
|
4405
|
+
tokenData = sourceTokenInput;
|
|
4406
|
+
}
|
|
4244
4407
|
}
|
|
4245
4408
|
} else if (payload.token) {
|
|
4246
4409
|
tokenData = payload.token;
|
|
@@ -4274,7 +4437,7 @@ var PaymentsModule = class {
|
|
|
4274
4437
|
await this.addToken(token);
|
|
4275
4438
|
const incomingTransfer = {
|
|
4276
4439
|
id: transfer.id,
|
|
4277
|
-
senderPubkey: transfer.
|
|
4440
|
+
senderPubkey: transfer.senderTransportPubkey,
|
|
4278
4441
|
tokens: [token],
|
|
4279
4442
|
memo: payload.memo,
|
|
4280
4443
|
receivedAt: transfer.timestamp
|
|
@@ -4342,7 +4505,7 @@ var PaymentsModule = class {
|
|
|
4342
4505
|
tokens,
|
|
4343
4506
|
{
|
|
4344
4507
|
version: 1,
|
|
4345
|
-
address: this.deps.identity.
|
|
4508
|
+
address: this.deps.identity.l1Address,
|
|
4346
4509
|
ipnsName: this.deps.identity.ipnsName ?? ""
|
|
4347
4510
|
},
|
|
4348
4511
|
{
|
|
@@ -4446,7 +4609,7 @@ var CommunicationsModule = class {
|
|
|
4446
4609
|
const eventId = await this.deps.transport.sendMessage(recipientPubkey, content);
|
|
4447
4610
|
const message = {
|
|
4448
4611
|
id: eventId,
|
|
4449
|
-
senderPubkey: this.deps.identity.
|
|
4612
|
+
senderPubkey: this.deps.identity.chainPubkey,
|
|
4450
4613
|
senderNametag: this.deps.identity.nametag,
|
|
4451
4614
|
recipientPubkey,
|
|
4452
4615
|
content,
|
|
@@ -4473,7 +4636,7 @@ var CommunicationsModule = class {
|
|
|
4473
4636
|
getConversations() {
|
|
4474
4637
|
const conversations = /* @__PURE__ */ new Map();
|
|
4475
4638
|
for (const message of this.messages.values()) {
|
|
4476
|
-
const peer = message.senderPubkey === this.deps?.identity.
|
|
4639
|
+
const peer = message.senderPubkey === this.deps?.identity.chainPubkey ? message.recipientPubkey : message.senderPubkey;
|
|
4477
4640
|
if (!conversations.has(peer)) {
|
|
4478
4641
|
conversations.set(peer, []);
|
|
4479
4642
|
}
|
|
@@ -4503,7 +4666,7 @@ var CommunicationsModule = class {
|
|
|
4503
4666
|
*/
|
|
4504
4667
|
getUnreadCount(peerPubkey) {
|
|
4505
4668
|
let messages = Array.from(this.messages.values()).filter(
|
|
4506
|
-
(m) => !m.isRead && m.senderPubkey !== this.deps?.identity.
|
|
4669
|
+
(m) => !m.isRead && m.senderPubkey !== this.deps?.identity.chainPubkey
|
|
4507
4670
|
);
|
|
4508
4671
|
if (peerPubkey) {
|
|
4509
4672
|
messages = messages.filter((m) => m.senderPubkey === peerPubkey);
|
|
@@ -4528,7 +4691,7 @@ var CommunicationsModule = class {
|
|
|
4528
4691
|
const eventId = await this.deps.transport.publishBroadcast?.(content, tags);
|
|
4529
4692
|
const message = {
|
|
4530
4693
|
id: eventId ?? crypto.randomUUID(),
|
|
4531
|
-
authorPubkey: this.deps.identity.
|
|
4694
|
+
authorPubkey: this.deps.identity.chainPubkey,
|
|
4532
4695
|
authorNametag: this.deps.identity.nametag,
|
|
4533
4696
|
content,
|
|
4534
4697
|
timestamp: Date.now(),
|
|
@@ -4579,11 +4742,12 @@ var CommunicationsModule = class {
|
|
|
4579
4742
|
// Private: Message Handling
|
|
4580
4743
|
// ===========================================================================
|
|
4581
4744
|
handleIncomingMessage(msg) {
|
|
4582
|
-
if (msg.
|
|
4745
|
+
if (msg.senderTransportPubkey === this.deps?.identity.chainPubkey) return;
|
|
4583
4746
|
const message = {
|
|
4584
4747
|
id: msg.id,
|
|
4585
|
-
senderPubkey: msg.
|
|
4586
|
-
|
|
4748
|
+
senderPubkey: msg.senderTransportPubkey,
|
|
4749
|
+
senderNametag: msg.senderNametag,
|
|
4750
|
+
recipientPubkey: this.deps.identity.chainPubkey,
|
|
4587
4751
|
content: msg.content,
|
|
4588
4752
|
timestamp: msg.timestamp,
|
|
4589
4753
|
isRead: false
|
|
@@ -4605,7 +4769,7 @@ var CommunicationsModule = class {
|
|
|
4605
4769
|
handleIncomingBroadcast(incoming) {
|
|
4606
4770
|
const message = {
|
|
4607
4771
|
id: incoming.id,
|
|
4608
|
-
authorPubkey: incoming.
|
|
4772
|
+
authorPubkey: incoming.authorTransportPubkey,
|
|
4609
4773
|
content: incoming.content,
|
|
4610
4774
|
timestamp: incoming.timestamp,
|
|
4611
4775
|
tags: incoming.tags
|
|
@@ -5432,6 +5596,7 @@ var import_SigningService2 = require("@unicitylabs/state-transition-sdk/lib/sign
|
|
|
5432
5596
|
var import_TokenType2 = require("@unicitylabs/state-transition-sdk/lib/token/TokenType");
|
|
5433
5597
|
var import_HashAlgorithm4 = require("@unicitylabs/state-transition-sdk/lib/hash/HashAlgorithm");
|
|
5434
5598
|
var import_UnmaskedPredicateReference2 = require("@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicateReference");
|
|
5599
|
+
var import_nostr_js_sdk = require("@unicitylabs/nostr-js-sdk");
|
|
5435
5600
|
var UNICITY_TOKEN_TYPE_HEX2 = "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509";
|
|
5436
5601
|
async function deriveL3PredicateAddress(privateKey) {
|
|
5437
5602
|
const secret = Buffer.from(privateKey, "hex");
|
|
@@ -5589,6 +5754,8 @@ var Sphere = class _Sphere {
|
|
|
5589
5754
|
_Sphere.instance = sphere;
|
|
5590
5755
|
if (options.nametag) {
|
|
5591
5756
|
await sphere.registerNametag(options.nametag);
|
|
5757
|
+
} else {
|
|
5758
|
+
await sphere.recoverNametagFromNostr();
|
|
5592
5759
|
}
|
|
5593
5760
|
return sphere;
|
|
5594
5761
|
}
|
|
@@ -5651,6 +5818,9 @@ var Sphere = class _Sphere {
|
|
|
5651
5818
|
}
|
|
5652
5819
|
await sphere.initializeProviders();
|
|
5653
5820
|
await sphere.initializeModules();
|
|
5821
|
+
if (!options.nametag) {
|
|
5822
|
+
await sphere.recoverNametagFromNostr();
|
|
5823
|
+
}
|
|
5654
5824
|
await sphere.finalizeWalletCreation();
|
|
5655
5825
|
sphere._initialized = true;
|
|
5656
5826
|
_Sphere.instance = sphere;
|
|
@@ -5724,9 +5894,9 @@ var Sphere = class _Sphere {
|
|
|
5724
5894
|
get identity() {
|
|
5725
5895
|
if (!this._identity) return null;
|
|
5726
5896
|
return {
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5897
|
+
chainPubkey: this._identity.chainPubkey,
|
|
5898
|
+
l1Address: this._identity.l1Address,
|
|
5899
|
+
directAddress: this._identity.directAddress,
|
|
5730
5900
|
ipnsName: this._identity.ipnsName,
|
|
5731
5901
|
nametag: this._identity.nametag
|
|
5732
5902
|
};
|
|
@@ -5843,7 +6013,7 @@ var Sphere = class _Sphere {
|
|
|
5843
6013
|
if (this._masterKey) {
|
|
5844
6014
|
address0 = this.deriveAddress(0).address;
|
|
5845
6015
|
} else if (this._identity) {
|
|
5846
|
-
address0 = this._identity.
|
|
6016
|
+
address0 = this._identity.l1Address;
|
|
5847
6017
|
}
|
|
5848
6018
|
} catch {
|
|
5849
6019
|
}
|
|
@@ -5890,8 +6060,8 @@ var Sphere = class _Sphere {
|
|
|
5890
6060
|
} catch {
|
|
5891
6061
|
if (i === 0 && this._identity) {
|
|
5892
6062
|
addresses.push({
|
|
5893
|
-
address: this._identity.
|
|
5894
|
-
publicKey: this._identity.
|
|
6063
|
+
address: this._identity.l1Address,
|
|
6064
|
+
publicKey: this._identity.chainPubkey,
|
|
5895
6065
|
path: this.getDefaultAddressPath(),
|
|
5896
6066
|
index: 0
|
|
5897
6067
|
});
|
|
@@ -5970,7 +6140,7 @@ var Sphere = class _Sphere {
|
|
|
5970
6140
|
} catch {
|
|
5971
6141
|
if (i === 0 && this._identity) {
|
|
5972
6142
|
addresses.push({
|
|
5973
|
-
address: this._identity.
|
|
6143
|
+
address: this._identity.l1Address,
|
|
5974
6144
|
path: this.getDefaultAddressPath(),
|
|
5975
6145
|
index: 0,
|
|
5976
6146
|
isChange: false
|
|
@@ -6324,9 +6494,9 @@ var Sphere = class _Sphere {
|
|
|
6324
6494
|
const nametag = this._addressNametags.get(index);
|
|
6325
6495
|
this._identity = {
|
|
6326
6496
|
privateKey: addressInfo.privateKey,
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
predicateAddress,
|
|
6497
|
+
chainPubkey: addressInfo.publicKey,
|
|
6498
|
+
l1Address: addressInfo.address,
|
|
6499
|
+
directAddress: predicateAddress,
|
|
6330
6500
|
ipnsName: "12D3KooW" + ipnsHash,
|
|
6331
6501
|
nametag
|
|
6332
6502
|
};
|
|
@@ -6339,13 +6509,13 @@ var Sphere = class _Sphere {
|
|
|
6339
6509
|
}
|
|
6340
6510
|
await this.reinitializeModulesForNewAddress();
|
|
6341
6511
|
this.emitEvent("identity:changed", {
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6512
|
+
l1Address: this._identity.l1Address,
|
|
6513
|
+
directAddress: this._identity.directAddress,
|
|
6514
|
+
chainPubkey: this._identity.chainPubkey,
|
|
6345
6515
|
nametag: this._identity.nametag,
|
|
6346
6516
|
addressIndex: index
|
|
6347
6517
|
});
|
|
6348
|
-
console.log(`[Sphere] Switched to address ${index}:`, this._identity.
|
|
6518
|
+
console.log(`[Sphere] Switched to address ${index}:`, this._identity.l1Address);
|
|
6349
6519
|
}
|
|
6350
6520
|
/**
|
|
6351
6521
|
* Re-initialize modules after address switch
|
|
@@ -6403,7 +6573,7 @@ var Sphere = class _Sphere {
|
|
|
6403
6573
|
);
|
|
6404
6574
|
return {
|
|
6405
6575
|
...info,
|
|
6406
|
-
address:
|
|
6576
|
+
address: publicKeyToAddress(info.publicKey, "alpha")
|
|
6407
6577
|
};
|
|
6408
6578
|
}
|
|
6409
6579
|
/**
|
|
@@ -6430,11 +6600,10 @@ var Sphere = class _Sphere {
|
|
|
6430
6600
|
path
|
|
6431
6601
|
);
|
|
6432
6602
|
const publicKey = getPublicKey(derived.privateKey);
|
|
6433
|
-
const addressHash = hash160(publicKey);
|
|
6434
6603
|
return {
|
|
6435
6604
|
privateKey: derived.privateKey,
|
|
6436
6605
|
publicKey,
|
|
6437
|
-
address:
|
|
6606
|
+
address: publicKeyToAddress(publicKey, "alpha"),
|
|
6438
6607
|
path,
|
|
6439
6608
|
index
|
|
6440
6609
|
};
|
|
@@ -6522,6 +6691,17 @@ var Sphere = class _Sphere {
|
|
|
6522
6691
|
hasNametag() {
|
|
6523
6692
|
return !!this._identity?.nametag;
|
|
6524
6693
|
}
|
|
6694
|
+
/**
|
|
6695
|
+
* Get the PROXY address for the current nametag
|
|
6696
|
+
* PROXY addresses are derived from the nametag hash and require
|
|
6697
|
+
* the nametag token to claim funds sent to them
|
|
6698
|
+
* @returns PROXY address string or undefined if no nametag
|
|
6699
|
+
*/
|
|
6700
|
+
getProxyAddress() {
|
|
6701
|
+
const nametag = this._identity?.nametag;
|
|
6702
|
+
if (!nametag) return void 0;
|
|
6703
|
+
return `PROXY:${(0, import_nostr_js_sdk.hashNametag)(nametag)}`;
|
|
6704
|
+
}
|
|
6525
6705
|
/**
|
|
6526
6706
|
* Register a nametag for the current active address
|
|
6527
6707
|
* Each address can have its own independent nametag
|
|
@@ -6550,7 +6730,11 @@ var Sphere = class _Sphere {
|
|
|
6550
6730
|
throw new Error(`Nametag already registered for address ${this._currentAddressIndex}: @${this._identity.nametag}`);
|
|
6551
6731
|
}
|
|
6552
6732
|
if (this._transport.registerNametag) {
|
|
6553
|
-
const success = await this._transport.registerNametag(
|
|
6733
|
+
const success = await this._transport.registerNametag(
|
|
6734
|
+
cleanNametag,
|
|
6735
|
+
this._identity.chainPubkey,
|
|
6736
|
+
this._identity.directAddress || ""
|
|
6737
|
+
);
|
|
6554
6738
|
if (!success) {
|
|
6555
6739
|
throw new Error("Failed to register nametag. It may already be taken.");
|
|
6556
6740
|
}
|
|
@@ -6644,7 +6828,11 @@ var Sphere = class _Sphere {
|
|
|
6644
6828
|
return;
|
|
6645
6829
|
}
|
|
6646
6830
|
try {
|
|
6647
|
-
const success = await this._transport.registerNametag(
|
|
6831
|
+
const success = await this._transport.registerNametag(
|
|
6832
|
+
nametag,
|
|
6833
|
+
this._identity.chainPubkey,
|
|
6834
|
+
this._identity.directAddress || ""
|
|
6835
|
+
);
|
|
6648
6836
|
if (success) {
|
|
6649
6837
|
console.log(`[Sphere] Nametag @${nametag} synced with Nostr`);
|
|
6650
6838
|
} else {
|
|
@@ -6654,6 +6842,38 @@ var Sphere = class _Sphere {
|
|
|
6654
6842
|
console.warn(`[Sphere] Nametag sync failed:`, error);
|
|
6655
6843
|
}
|
|
6656
6844
|
}
|
|
6845
|
+
/**
|
|
6846
|
+
* Recover nametag from Nostr after wallet import
|
|
6847
|
+
* Searches for encrypted nametag events authored by this wallet's pubkey
|
|
6848
|
+
* and decrypts them to restore the nametag association
|
|
6849
|
+
*/
|
|
6850
|
+
async recoverNametagFromNostr() {
|
|
6851
|
+
if (this._identity?.nametag) {
|
|
6852
|
+
return;
|
|
6853
|
+
}
|
|
6854
|
+
if (!this._transport.recoverNametag) {
|
|
6855
|
+
return;
|
|
6856
|
+
}
|
|
6857
|
+
try {
|
|
6858
|
+
const recoveredNametag = await this._transport.recoverNametag();
|
|
6859
|
+
if (recoveredNametag) {
|
|
6860
|
+
if (this._identity) {
|
|
6861
|
+
this._identity.nametag = recoveredNametag;
|
|
6862
|
+
}
|
|
6863
|
+
this._addressNametags.set(this._currentAddressIndex, recoveredNametag);
|
|
6864
|
+
await this._storage.set(STORAGE_KEYS.NAMETAG, recoveredNametag);
|
|
6865
|
+
if (this._transport.registerNametag) {
|
|
6866
|
+
await this._transport.registerNametag(
|
|
6867
|
+
recoveredNametag,
|
|
6868
|
+
this._identity.chainPubkey,
|
|
6869
|
+
this._identity.directAddress || ""
|
|
6870
|
+
);
|
|
6871
|
+
}
|
|
6872
|
+
this.emitEvent("nametag:recovered", { nametag: recoveredNametag });
|
|
6873
|
+
}
|
|
6874
|
+
} catch {
|
|
6875
|
+
}
|
|
6876
|
+
}
|
|
6657
6877
|
/**
|
|
6658
6878
|
* Validate nametag format
|
|
6659
6879
|
*/
|
|
@@ -6780,57 +7000,64 @@ var Sphere = class _Sphere {
|
|
|
6780
7000
|
const nametag = this._addressNametags.get(this._currentAddressIndex);
|
|
6781
7001
|
this._identity = {
|
|
6782
7002
|
privateKey: addressInfo.privateKey,
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
predicateAddress,
|
|
7003
|
+
chainPubkey: addressInfo.publicKey,
|
|
7004
|
+
l1Address: addressInfo.address,
|
|
7005
|
+
directAddress: predicateAddress,
|
|
6786
7006
|
ipnsName: "12D3KooW" + ipnsHash,
|
|
6787
7007
|
nametag
|
|
6788
7008
|
};
|
|
6789
7009
|
this._storage.setIdentity(this._identity);
|
|
6790
|
-
console.log(`[Sphere] Restored to address ${this._currentAddressIndex}:`, this._identity.
|
|
7010
|
+
console.log(`[Sphere] Restored to address ${this._currentAddressIndex}:`, this._identity.l1Address);
|
|
6791
7011
|
} else {
|
|
6792
7012
|
if (savedNametag && this._identity) {
|
|
6793
|
-
|
|
7013
|
+
let nametag = savedNametag;
|
|
7014
|
+
if (savedNametag.startsWith("{")) {
|
|
7015
|
+
try {
|
|
7016
|
+
const parsed = JSON.parse(savedNametag);
|
|
7017
|
+
nametag = parsed["0"] || parsed[0] || Object.values(parsed)[0];
|
|
7018
|
+
} catch {
|
|
7019
|
+
}
|
|
7020
|
+
}
|
|
7021
|
+
this._identity.nametag = nametag;
|
|
6794
7022
|
if (!this._addressNametags.has(0)) {
|
|
6795
|
-
this._addressNametags.set(0,
|
|
7023
|
+
this._addressNametags.set(0, nametag);
|
|
6796
7024
|
}
|
|
6797
|
-
console.log("[Sphere] Restored nametag:", savedNametag);
|
|
6798
7025
|
} else if (this._identity) {
|
|
6799
7026
|
const nametag = this._addressNametags.get(0);
|
|
6800
7027
|
if (nametag) {
|
|
6801
7028
|
this._identity.nametag = nametag;
|
|
6802
|
-
console.log("[Sphere] Restored nametag from map:", nametag);
|
|
6803
7029
|
}
|
|
6804
7030
|
}
|
|
6805
7031
|
}
|
|
6806
7032
|
}
|
|
6807
7033
|
async initializeIdentityFromMnemonic(mnemonic, derivationPath) {
|
|
6808
|
-
const
|
|
7034
|
+
const basePath = derivationPath ?? DEFAULT_BASE_PATH;
|
|
7035
|
+
const fullPath = `${basePath}/0/0`;
|
|
6809
7036
|
const masterKey = identityFromMnemonicSync(mnemonic);
|
|
6810
7037
|
const derivedKey = deriveKeyAtPath(
|
|
6811
7038
|
masterKey.privateKey,
|
|
6812
7039
|
masterKey.chainCode,
|
|
6813
|
-
|
|
7040
|
+
fullPath
|
|
6814
7041
|
);
|
|
6815
7042
|
const publicKey = getPublicKey(derivedKey.privateKey);
|
|
6816
|
-
const
|
|
7043
|
+
const address = publicKeyToAddress(publicKey, "alpha");
|
|
6817
7044
|
const ipnsHash = sha256(publicKey, "hex").slice(0, 40);
|
|
6818
7045
|
const predicateAddress = await deriveL3PredicateAddress(derivedKey.privateKey);
|
|
6819
7046
|
this._identity = {
|
|
6820
7047
|
privateKey: derivedKey.privateKey,
|
|
6821
|
-
publicKey,
|
|
6822
|
-
|
|
6823
|
-
predicateAddress,
|
|
7048
|
+
chainPubkey: publicKey,
|
|
7049
|
+
l1Address: address,
|
|
7050
|
+
directAddress: predicateAddress,
|
|
6824
7051
|
ipnsName: "12D3KooW" + ipnsHash
|
|
6825
7052
|
};
|
|
6826
7053
|
this._masterKey = masterKey;
|
|
6827
|
-
console.log("[Sphere] Identity initialized from mnemonic, path:", path);
|
|
6828
7054
|
}
|
|
6829
7055
|
async initializeIdentityFromMasterKey(masterKey, chainCode, derivationPath) {
|
|
6830
|
-
const
|
|
7056
|
+
const basePath = derivationPath ?? DEFAULT_BASE_PATH;
|
|
7057
|
+
const fullPath = `${basePath}/0/0`;
|
|
6831
7058
|
let privateKey;
|
|
6832
7059
|
if (chainCode) {
|
|
6833
|
-
const derivedKey = deriveKeyAtPath(masterKey, chainCode,
|
|
7060
|
+
const derivedKey = deriveKeyAtPath(masterKey, chainCode, fullPath);
|
|
6834
7061
|
privateKey = derivedKey.privateKey;
|
|
6835
7062
|
this._masterKey = {
|
|
6836
7063
|
privateKey: masterKey,
|
|
@@ -6841,17 +7068,16 @@ var Sphere = class _Sphere {
|
|
|
6841
7068
|
this._masterKey = null;
|
|
6842
7069
|
}
|
|
6843
7070
|
const publicKey = getPublicKey(privateKey);
|
|
6844
|
-
const
|
|
7071
|
+
const address = publicKeyToAddress(publicKey, "alpha");
|
|
6845
7072
|
const ipnsHash = sha256(publicKey, "hex").slice(0, 40);
|
|
6846
7073
|
const predicateAddress = await deriveL3PredicateAddress(privateKey);
|
|
6847
7074
|
this._identity = {
|
|
6848
7075
|
privateKey,
|
|
6849
|
-
publicKey,
|
|
6850
|
-
|
|
6851
|
-
predicateAddress,
|
|
7076
|
+
chainPubkey: publicKey,
|
|
7077
|
+
l1Address: address,
|
|
7078
|
+
directAddress: predicateAddress,
|
|
6852
7079
|
ipnsName: "12D3KooW" + ipnsHash
|
|
6853
7080
|
};
|
|
6854
|
-
console.log("[Sphere] Identity initialized from master key, path:", path, "chainCode:", !!chainCode);
|
|
6855
7081
|
}
|
|
6856
7082
|
// ===========================================================================
|
|
6857
7083
|
// Private: Provider & Module Initialization
|