@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.js
CHANGED
|
@@ -1350,6 +1350,7 @@ var L1PaymentsModule = class {
|
|
|
1350
1350
|
_chainCode;
|
|
1351
1351
|
_addresses = [];
|
|
1352
1352
|
_wallet;
|
|
1353
|
+
_transport;
|
|
1353
1354
|
constructor(config) {
|
|
1354
1355
|
this._config = {
|
|
1355
1356
|
electrumUrl: config?.electrumUrl ?? "wss://fulcrum.alpha.unicity.network:50004",
|
|
@@ -1362,13 +1363,14 @@ var L1PaymentsModule = class {
|
|
|
1362
1363
|
this._identity = deps.identity;
|
|
1363
1364
|
this._chainCode = deps.chainCode;
|
|
1364
1365
|
this._addresses = deps.addresses ?? [];
|
|
1366
|
+
this._transport = deps.transport;
|
|
1365
1367
|
this._wallet = {
|
|
1366
1368
|
masterPrivateKey: deps.identity.privateKey,
|
|
1367
1369
|
chainCode: deps.chainCode,
|
|
1368
1370
|
addresses: [
|
|
1369
1371
|
{
|
|
1370
|
-
address: deps.identity.
|
|
1371
|
-
publicKey: deps.identity.
|
|
1372
|
+
address: deps.identity.l1Address,
|
|
1373
|
+
publicKey: deps.identity.chainPubkey,
|
|
1372
1374
|
privateKey: deps.identity.privateKey,
|
|
1373
1375
|
path: "m/0",
|
|
1374
1376
|
index: 0
|
|
@@ -1376,7 +1378,7 @@ var L1PaymentsModule = class {
|
|
|
1376
1378
|
]
|
|
1377
1379
|
};
|
|
1378
1380
|
for (const addr of this._addresses) {
|
|
1379
|
-
if (addr !== deps.identity.
|
|
1381
|
+
if (addr !== deps.identity.l1Address) {
|
|
1380
1382
|
this._wallet.addresses.push({
|
|
1381
1383
|
address: addr,
|
|
1382
1384
|
path: null,
|
|
@@ -1399,18 +1401,64 @@ var L1PaymentsModule = class {
|
|
|
1399
1401
|
this._addresses = [];
|
|
1400
1402
|
this._wallet = void 0;
|
|
1401
1403
|
}
|
|
1404
|
+
/**
|
|
1405
|
+
* Check if a string looks like an L1 address (alpha1... or alphat1...)
|
|
1406
|
+
*/
|
|
1407
|
+
isL1Address(value) {
|
|
1408
|
+
return value.startsWith("alpha1") || value.startsWith("alphat1");
|
|
1409
|
+
}
|
|
1410
|
+
/**
|
|
1411
|
+
* Resolve recipient to L1 address
|
|
1412
|
+
* Supports: L1 address (alpha1...), nametag (with or without @)
|
|
1413
|
+
*/
|
|
1414
|
+
async resolveL1Address(recipient) {
|
|
1415
|
+
if (recipient.startsWith("@")) {
|
|
1416
|
+
const nametag = recipient.slice(1);
|
|
1417
|
+
return this.resolveNametagToL1Address(nametag);
|
|
1418
|
+
}
|
|
1419
|
+
if (this.isL1Address(recipient)) {
|
|
1420
|
+
return recipient;
|
|
1421
|
+
}
|
|
1422
|
+
try {
|
|
1423
|
+
const l1Address = await this.resolveNametagToL1Address(recipient);
|
|
1424
|
+
return l1Address;
|
|
1425
|
+
} catch {
|
|
1426
|
+
throw new Error(
|
|
1427
|
+
`Recipient "${recipient}" is not a valid nametag or L1 address. Use @nametag for explicit nametag or a valid alpha1... address.`
|
|
1428
|
+
);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* Resolve nametag to L1 address using transport provider
|
|
1433
|
+
*/
|
|
1434
|
+
async resolveNametagToL1Address(nametag) {
|
|
1435
|
+
if (!this._transport?.resolveNametagInfo) {
|
|
1436
|
+
throw new Error("Transport provider does not support nametag resolution");
|
|
1437
|
+
}
|
|
1438
|
+
const info = await this._transport.resolveNametagInfo(nametag);
|
|
1439
|
+
if (!info) {
|
|
1440
|
+
throw new Error(`Nametag not found: ${nametag}`);
|
|
1441
|
+
}
|
|
1442
|
+
if (!info.l1Address) {
|
|
1443
|
+
throw new Error(
|
|
1444
|
+
`Nametag @${nametag} does not have L1 address information. The owner needs to update their nametag registration.`
|
|
1445
|
+
);
|
|
1446
|
+
}
|
|
1447
|
+
return info.l1Address;
|
|
1448
|
+
}
|
|
1402
1449
|
async send(request) {
|
|
1403
1450
|
this.ensureInitialized();
|
|
1404
1451
|
if (!this._wallet || !this._identity) {
|
|
1405
1452
|
return { success: false, error: "No wallet available" };
|
|
1406
1453
|
}
|
|
1407
1454
|
try {
|
|
1455
|
+
const recipientAddress = await this.resolveL1Address(request.to);
|
|
1408
1456
|
const amountAlpha = parseInt(request.amount, 10) / 1e8;
|
|
1409
1457
|
const results = await sendAlpha(
|
|
1410
1458
|
this._wallet,
|
|
1411
|
-
|
|
1459
|
+
recipientAddress,
|
|
1412
1460
|
amountAlpha,
|
|
1413
|
-
this._identity.
|
|
1461
|
+
this._identity.l1Address
|
|
1414
1462
|
);
|
|
1415
1463
|
if (results && results.length > 0) {
|
|
1416
1464
|
const txids = results.map((r) => r.txid);
|
|
@@ -1632,8 +1680,8 @@ var L1PaymentsModule = class {
|
|
|
1632
1680
|
}
|
|
1633
1681
|
_getWatchedAddresses() {
|
|
1634
1682
|
const addresses = [...this._addresses];
|
|
1635
|
-
if (this._identity?.
|
|
1636
|
-
addresses.unshift(this._identity.
|
|
1683
|
+
if (this._identity?.l1Address && !addresses.includes(this._identity.l1Address)) {
|
|
1684
|
+
addresses.unshift(this._identity.l1Address);
|
|
1637
1685
|
}
|
|
1638
1686
|
return addresses;
|
|
1639
1687
|
}
|
|
@@ -2475,12 +2523,10 @@ function getCurrentStateHash(txf) {
|
|
|
2475
2523
|
|
|
2476
2524
|
// modules/payments/PaymentsModule.ts
|
|
2477
2525
|
import { Token as SdkToken2 } from "@unicitylabs/state-transition-sdk/lib/token/Token";
|
|
2478
|
-
import { TokenId as TokenId3 } from "@unicitylabs/state-transition-sdk/lib/token/TokenId";
|
|
2479
2526
|
import { CoinId as CoinId3 } from "@unicitylabs/state-transition-sdk/lib/token/fungible/CoinId";
|
|
2480
2527
|
import { TransferCommitment as TransferCommitment2 } from "@unicitylabs/state-transition-sdk/lib/transaction/TransferCommitment";
|
|
2481
2528
|
import { TransferTransaction } from "@unicitylabs/state-transition-sdk/lib/transaction/TransferTransaction";
|
|
2482
2529
|
import { SigningService } from "@unicitylabs/state-transition-sdk/lib/sign/SigningService";
|
|
2483
|
-
import { ProxyAddress } from "@unicitylabs/state-transition-sdk/lib/address/ProxyAddress";
|
|
2484
2530
|
import { AddressScheme } from "@unicitylabs/state-transition-sdk/lib/address/AddressScheme";
|
|
2485
2531
|
import { UnmaskedPredicate as UnmaskedPredicate3 } from "@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicate";
|
|
2486
2532
|
import { TokenState as TokenState3 } from "@unicitylabs/state-transition-sdk/lib/token/TokenState";
|
|
@@ -2771,7 +2817,8 @@ var PaymentsModule = class {
|
|
|
2771
2817
|
this.l1.initialize({
|
|
2772
2818
|
identity: deps.identity,
|
|
2773
2819
|
chainCode: deps.chainCode,
|
|
2774
|
-
addresses: deps.l1Addresses
|
|
2820
|
+
addresses: deps.l1Addresses,
|
|
2821
|
+
transport: deps.transport
|
|
2775
2822
|
});
|
|
2776
2823
|
}
|
|
2777
2824
|
this.unsubscribeTransfers = deps.transport.onTokenTransfer((transfer) => {
|
|
@@ -3168,7 +3215,7 @@ var PaymentsModule = class {
|
|
|
3168
3215
|
}
|
|
3169
3216
|
const request = {
|
|
3170
3217
|
id: transportRequest.id,
|
|
3171
|
-
senderPubkey: transportRequest.
|
|
3218
|
+
senderPubkey: transportRequest.senderTransportPubkey,
|
|
3172
3219
|
amount: transportRequest.request.amount,
|
|
3173
3220
|
coinId: transportRequest.request.coinId,
|
|
3174
3221
|
symbol: transportRequest.request.coinId,
|
|
@@ -3280,7 +3327,7 @@ var PaymentsModule = class {
|
|
|
3280
3327
|
}
|
|
3281
3328
|
const response = {
|
|
3282
3329
|
id: transportResponse.id,
|
|
3283
|
-
responderPubkey: transportResponse.
|
|
3330
|
+
responderPubkey: transportResponse.responderTransportPubkey,
|
|
3284
3331
|
requestId: transportResponse.response.requestId,
|
|
3285
3332
|
responseType: transportResponse.response.responseType,
|
|
3286
3333
|
message: transportResponse.response.message,
|
|
@@ -4034,6 +4081,23 @@ var PaymentsModule = class {
|
|
|
4034
4081
|
// ===========================================================================
|
|
4035
4082
|
// Private: Transfer Operations
|
|
4036
4083
|
// ===========================================================================
|
|
4084
|
+
/**
|
|
4085
|
+
* Detect if a string is an L3 address (not a nametag)
|
|
4086
|
+
* Returns true for: hex pubkeys (64+ chars), PROXY:, DIRECT: prefixed addresses
|
|
4087
|
+
*/
|
|
4088
|
+
isL3Address(value) {
|
|
4089
|
+
if (value.startsWith("PROXY:") || value.startsWith("DIRECT:")) {
|
|
4090
|
+
return true;
|
|
4091
|
+
}
|
|
4092
|
+
if (value.length >= 64 && /^[0-9a-fA-F]+$/.test(value)) {
|
|
4093
|
+
return true;
|
|
4094
|
+
}
|
|
4095
|
+
return false;
|
|
4096
|
+
}
|
|
4097
|
+
/**
|
|
4098
|
+
* Resolve recipient to Nostr pubkey for messaging
|
|
4099
|
+
* Supports: nametag (with or without @), hex pubkey
|
|
4100
|
+
*/
|
|
4037
4101
|
async resolveRecipient(recipient) {
|
|
4038
4102
|
if (recipient.startsWith("@")) {
|
|
4039
4103
|
const nametag = recipient.slice(1);
|
|
@@ -4043,7 +4107,19 @@ var PaymentsModule = class {
|
|
|
4043
4107
|
}
|
|
4044
4108
|
return pubkey;
|
|
4045
4109
|
}
|
|
4046
|
-
|
|
4110
|
+
if (this.isL3Address(recipient)) {
|
|
4111
|
+
return recipient;
|
|
4112
|
+
}
|
|
4113
|
+
if (this.deps?.transport.resolveNametag) {
|
|
4114
|
+
const pubkey = await this.deps.transport.resolveNametag(recipient);
|
|
4115
|
+
if (pubkey) {
|
|
4116
|
+
this.log(`Resolved "${recipient}" as nametag to pubkey`);
|
|
4117
|
+
return pubkey;
|
|
4118
|
+
}
|
|
4119
|
+
}
|
|
4120
|
+
throw new Error(
|
|
4121
|
+
`Recipient "${recipient}" is not a valid nametag or address. Use @nametag for explicit nametag or a valid hex pubkey/PROXY:/DIRECT: address.`
|
|
4122
|
+
);
|
|
4047
4123
|
}
|
|
4048
4124
|
/**
|
|
4049
4125
|
* Create SDK TransferCommitment for a token transfer
|
|
@@ -4075,19 +4151,74 @@ var PaymentsModule = class {
|
|
|
4075
4151
|
return SigningService.createFromSecret(privateKeyBytes);
|
|
4076
4152
|
}
|
|
4077
4153
|
/**
|
|
4078
|
-
*
|
|
4154
|
+
* Create DirectAddress from a public key using UnmaskedPredicateReference
|
|
4155
|
+
*/
|
|
4156
|
+
async createDirectAddressFromPubkey(pubkeyHex) {
|
|
4157
|
+
const { UnmaskedPredicateReference: UnmaskedPredicateReference3 } = await import("@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicateReference");
|
|
4158
|
+
const { TokenType: TokenType3 } = await import("@unicitylabs/state-transition-sdk/lib/token/TokenType");
|
|
4159
|
+
const UNICITY_TOKEN_TYPE_HEX3 = "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509";
|
|
4160
|
+
const tokenType = new TokenType3(Buffer.from(UNICITY_TOKEN_TYPE_HEX3, "hex"));
|
|
4161
|
+
const pubkeyBytes = new Uint8Array(
|
|
4162
|
+
pubkeyHex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))
|
|
4163
|
+
);
|
|
4164
|
+
const addressRef = await UnmaskedPredicateReference3.create(
|
|
4165
|
+
tokenType,
|
|
4166
|
+
"secp256k1",
|
|
4167
|
+
pubkeyBytes,
|
|
4168
|
+
HashAlgorithm3.SHA256
|
|
4169
|
+
);
|
|
4170
|
+
return addressRef.toAddress();
|
|
4171
|
+
}
|
|
4172
|
+
/**
|
|
4173
|
+
* Resolve nametag to 33-byte compressed public key using resolveNametagInfo
|
|
4174
|
+
* Returns null if nametag not found or publicKey not available
|
|
4175
|
+
*/
|
|
4176
|
+
async resolveNametagToPublicKey(nametag) {
|
|
4177
|
+
if (!this.deps?.transport.resolveNametagInfo) {
|
|
4178
|
+
this.log("resolveNametagInfo not available on transport");
|
|
4179
|
+
return null;
|
|
4180
|
+
}
|
|
4181
|
+
const info = await this.deps.transport.resolveNametagInfo(nametag);
|
|
4182
|
+
if (!info) {
|
|
4183
|
+
this.log(`Nametag "${nametag}" not found`);
|
|
4184
|
+
return null;
|
|
4185
|
+
}
|
|
4186
|
+
if (!info.chainPubkey) {
|
|
4187
|
+
this.log(`Nametag "${nametag}" has no 33-byte chainPubkey (legacy event)`);
|
|
4188
|
+
return null;
|
|
4189
|
+
}
|
|
4190
|
+
return info.chainPubkey;
|
|
4191
|
+
}
|
|
4192
|
+
/**
|
|
4193
|
+
* Resolve recipient to IAddress for L3 transfers
|
|
4194
|
+
* Supports: nametag (with or without @), PROXY:, DIRECT:, hex pubkey
|
|
4079
4195
|
*/
|
|
4080
4196
|
async resolveRecipientAddress(recipient) {
|
|
4197
|
+
const { AddressFactory } = await import("@unicitylabs/state-transition-sdk/lib/address/AddressFactory");
|
|
4081
4198
|
if (recipient.startsWith("@")) {
|
|
4082
4199
|
const nametag = recipient.slice(1);
|
|
4083
|
-
const
|
|
4084
|
-
|
|
4200
|
+
const publicKey2 = await this.resolveNametagToPublicKey(nametag);
|
|
4201
|
+
if (publicKey2) {
|
|
4202
|
+
this.log(`Resolved @${nametag} to 33-byte publicKey for DirectAddress`);
|
|
4203
|
+
return this.createDirectAddressFromPubkey(publicKey2);
|
|
4204
|
+
}
|
|
4205
|
+
throw new Error(`Nametag "${nametag}" not found or missing publicKey`);
|
|
4085
4206
|
}
|
|
4086
|
-
|
|
4087
|
-
|
|
4207
|
+
if (recipient.startsWith("PROXY:") || recipient.startsWith("DIRECT:")) {
|
|
4208
|
+
return AddressFactory.createAddress(recipient);
|
|
4209
|
+
}
|
|
4210
|
+
if (recipient.length === 66 && /^[0-9a-fA-F]+$/.test(recipient)) {
|
|
4211
|
+
this.log(`Creating DirectAddress from 33-byte compressed pubkey`);
|
|
4212
|
+
return this.createDirectAddressFromPubkey(recipient);
|
|
4213
|
+
}
|
|
4214
|
+
const publicKey = await this.resolveNametagToPublicKey(recipient);
|
|
4215
|
+
if (publicKey) {
|
|
4216
|
+
this.log(`Resolved "${recipient}" as nametag to 33-byte publicKey for DirectAddress`);
|
|
4217
|
+
return this.createDirectAddressFromPubkey(publicKey);
|
|
4218
|
+
}
|
|
4219
|
+
throw new Error(
|
|
4220
|
+
`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.`
|
|
4088
4221
|
);
|
|
4089
|
-
const tokenId = new TokenId3(pubkeyBytes.slice(0, 32));
|
|
4090
|
-
return ProxyAddress.fromTokenId(tokenId);
|
|
4091
4222
|
}
|
|
4092
4223
|
async handleIncomingTransfer(transfer) {
|
|
4093
4224
|
try {
|
|
@@ -4145,7 +4276,39 @@ var PaymentsModule = class {
|
|
|
4145
4276
|
}
|
|
4146
4277
|
}
|
|
4147
4278
|
} else {
|
|
4148
|
-
|
|
4279
|
+
this.log("Finalizing DIRECT address transfer for state tracking...");
|
|
4280
|
+
try {
|
|
4281
|
+
const signingService = await this.createSigningService();
|
|
4282
|
+
const transferSalt = transferTx.data.salt;
|
|
4283
|
+
const recipientPredicate = await UnmaskedPredicate3.create(
|
|
4284
|
+
sourceToken.id,
|
|
4285
|
+
sourceToken.type,
|
|
4286
|
+
signingService,
|
|
4287
|
+
HashAlgorithm3.SHA256,
|
|
4288
|
+
transferSalt
|
|
4289
|
+
);
|
|
4290
|
+
const recipientState = new TokenState3(recipientPredicate, null);
|
|
4291
|
+
const stClient = this.deps.oracle.getStateTransitionClient?.();
|
|
4292
|
+
const trustBase = this.deps.oracle.getTrustBase?.();
|
|
4293
|
+
if (!stClient || !trustBase) {
|
|
4294
|
+
this.log("Cannot finalize DIRECT transfer - missing client, using source token");
|
|
4295
|
+
tokenData = sourceTokenInput;
|
|
4296
|
+
} else {
|
|
4297
|
+
finalizedSdkToken = await stClient.finalizeTransaction(
|
|
4298
|
+
trustBase,
|
|
4299
|
+
sourceToken,
|
|
4300
|
+
recipientState,
|
|
4301
|
+
transferTx,
|
|
4302
|
+
[]
|
|
4303
|
+
// No nametag tokens needed for DIRECT
|
|
4304
|
+
);
|
|
4305
|
+
tokenData = finalizedSdkToken.toJSON();
|
|
4306
|
+
this.log("DIRECT transfer finalized successfully");
|
|
4307
|
+
}
|
|
4308
|
+
} catch (finalizeError) {
|
|
4309
|
+
this.log("DIRECT finalization failed, using source token:", finalizeError);
|
|
4310
|
+
tokenData = sourceTokenInput;
|
|
4311
|
+
}
|
|
4149
4312
|
}
|
|
4150
4313
|
} else if (payload.token) {
|
|
4151
4314
|
tokenData = payload.token;
|
|
@@ -4179,7 +4342,7 @@ var PaymentsModule = class {
|
|
|
4179
4342
|
await this.addToken(token);
|
|
4180
4343
|
const incomingTransfer = {
|
|
4181
4344
|
id: transfer.id,
|
|
4182
|
-
senderPubkey: transfer.
|
|
4345
|
+
senderPubkey: transfer.senderTransportPubkey,
|
|
4183
4346
|
tokens: [token],
|
|
4184
4347
|
memo: payload.memo,
|
|
4185
4348
|
receivedAt: transfer.timestamp
|
|
@@ -4247,7 +4410,7 @@ var PaymentsModule = class {
|
|
|
4247
4410
|
tokens,
|
|
4248
4411
|
{
|
|
4249
4412
|
version: 1,
|
|
4250
|
-
address: this.deps.identity.
|
|
4413
|
+
address: this.deps.identity.l1Address,
|
|
4251
4414
|
ipnsName: this.deps.identity.ipnsName ?? ""
|
|
4252
4415
|
},
|
|
4253
4416
|
{
|
|
@@ -4351,7 +4514,7 @@ var CommunicationsModule = class {
|
|
|
4351
4514
|
const eventId = await this.deps.transport.sendMessage(recipientPubkey, content);
|
|
4352
4515
|
const message = {
|
|
4353
4516
|
id: eventId,
|
|
4354
|
-
senderPubkey: this.deps.identity.
|
|
4517
|
+
senderPubkey: this.deps.identity.chainPubkey,
|
|
4355
4518
|
senderNametag: this.deps.identity.nametag,
|
|
4356
4519
|
recipientPubkey,
|
|
4357
4520
|
content,
|
|
@@ -4378,7 +4541,7 @@ var CommunicationsModule = class {
|
|
|
4378
4541
|
getConversations() {
|
|
4379
4542
|
const conversations = /* @__PURE__ */ new Map();
|
|
4380
4543
|
for (const message of this.messages.values()) {
|
|
4381
|
-
const peer = message.senderPubkey === this.deps?.identity.
|
|
4544
|
+
const peer = message.senderPubkey === this.deps?.identity.chainPubkey ? message.recipientPubkey : message.senderPubkey;
|
|
4382
4545
|
if (!conversations.has(peer)) {
|
|
4383
4546
|
conversations.set(peer, []);
|
|
4384
4547
|
}
|
|
@@ -4408,7 +4571,7 @@ var CommunicationsModule = class {
|
|
|
4408
4571
|
*/
|
|
4409
4572
|
getUnreadCount(peerPubkey) {
|
|
4410
4573
|
let messages = Array.from(this.messages.values()).filter(
|
|
4411
|
-
(m) => !m.isRead && m.senderPubkey !== this.deps?.identity.
|
|
4574
|
+
(m) => !m.isRead && m.senderPubkey !== this.deps?.identity.chainPubkey
|
|
4412
4575
|
);
|
|
4413
4576
|
if (peerPubkey) {
|
|
4414
4577
|
messages = messages.filter((m) => m.senderPubkey === peerPubkey);
|
|
@@ -4433,7 +4596,7 @@ var CommunicationsModule = class {
|
|
|
4433
4596
|
const eventId = await this.deps.transport.publishBroadcast?.(content, tags);
|
|
4434
4597
|
const message = {
|
|
4435
4598
|
id: eventId ?? crypto.randomUUID(),
|
|
4436
|
-
authorPubkey: this.deps.identity.
|
|
4599
|
+
authorPubkey: this.deps.identity.chainPubkey,
|
|
4437
4600
|
authorNametag: this.deps.identity.nametag,
|
|
4438
4601
|
content,
|
|
4439
4602
|
timestamp: Date.now(),
|
|
@@ -4484,11 +4647,12 @@ var CommunicationsModule = class {
|
|
|
4484
4647
|
// Private: Message Handling
|
|
4485
4648
|
// ===========================================================================
|
|
4486
4649
|
handleIncomingMessage(msg) {
|
|
4487
|
-
if (msg.
|
|
4650
|
+
if (msg.senderTransportPubkey === this.deps?.identity.chainPubkey) return;
|
|
4488
4651
|
const message = {
|
|
4489
4652
|
id: msg.id,
|
|
4490
|
-
senderPubkey: msg.
|
|
4491
|
-
|
|
4653
|
+
senderPubkey: msg.senderTransportPubkey,
|
|
4654
|
+
senderNametag: msg.senderNametag,
|
|
4655
|
+
recipientPubkey: this.deps.identity.chainPubkey,
|
|
4492
4656
|
content: msg.content,
|
|
4493
4657
|
timestamp: msg.timestamp,
|
|
4494
4658
|
isRead: false
|
|
@@ -4510,7 +4674,7 @@ var CommunicationsModule = class {
|
|
|
4510
4674
|
handleIncomingBroadcast(incoming) {
|
|
4511
4675
|
const message = {
|
|
4512
4676
|
id: incoming.id,
|
|
4513
|
-
authorPubkey: incoming.
|
|
4677
|
+
authorPubkey: incoming.authorTransportPubkey,
|
|
4514
4678
|
content: incoming.content,
|
|
4515
4679
|
timestamp: incoming.timestamp,
|
|
4516
4680
|
tags: incoming.tags
|
|
@@ -5337,6 +5501,7 @@ import { SigningService as SigningService2 } from "@unicitylabs/state-transition
|
|
|
5337
5501
|
import { TokenType as TokenType2 } from "@unicitylabs/state-transition-sdk/lib/token/TokenType";
|
|
5338
5502
|
import { HashAlgorithm as HashAlgorithm4 } from "@unicitylabs/state-transition-sdk/lib/hash/HashAlgorithm";
|
|
5339
5503
|
import { UnmaskedPredicateReference as UnmaskedPredicateReference2 } from "@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicateReference";
|
|
5504
|
+
import { hashNametag } from "@unicitylabs/nostr-js-sdk";
|
|
5340
5505
|
var UNICITY_TOKEN_TYPE_HEX2 = "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509";
|
|
5341
5506
|
async function deriveL3PredicateAddress(privateKey) {
|
|
5342
5507
|
const secret = Buffer.from(privateKey, "hex");
|
|
@@ -5494,6 +5659,8 @@ var Sphere = class _Sphere {
|
|
|
5494
5659
|
_Sphere.instance = sphere;
|
|
5495
5660
|
if (options.nametag) {
|
|
5496
5661
|
await sphere.registerNametag(options.nametag);
|
|
5662
|
+
} else {
|
|
5663
|
+
await sphere.recoverNametagFromNostr();
|
|
5497
5664
|
}
|
|
5498
5665
|
return sphere;
|
|
5499
5666
|
}
|
|
@@ -5556,6 +5723,9 @@ var Sphere = class _Sphere {
|
|
|
5556
5723
|
}
|
|
5557
5724
|
await sphere.initializeProviders();
|
|
5558
5725
|
await sphere.initializeModules();
|
|
5726
|
+
if (!options.nametag) {
|
|
5727
|
+
await sphere.recoverNametagFromNostr();
|
|
5728
|
+
}
|
|
5559
5729
|
await sphere.finalizeWalletCreation();
|
|
5560
5730
|
sphere._initialized = true;
|
|
5561
5731
|
_Sphere.instance = sphere;
|
|
@@ -5629,9 +5799,9 @@ var Sphere = class _Sphere {
|
|
|
5629
5799
|
get identity() {
|
|
5630
5800
|
if (!this._identity) return null;
|
|
5631
5801
|
return {
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5802
|
+
chainPubkey: this._identity.chainPubkey,
|
|
5803
|
+
l1Address: this._identity.l1Address,
|
|
5804
|
+
directAddress: this._identity.directAddress,
|
|
5635
5805
|
ipnsName: this._identity.ipnsName,
|
|
5636
5806
|
nametag: this._identity.nametag
|
|
5637
5807
|
};
|
|
@@ -5748,7 +5918,7 @@ var Sphere = class _Sphere {
|
|
|
5748
5918
|
if (this._masterKey) {
|
|
5749
5919
|
address0 = this.deriveAddress(0).address;
|
|
5750
5920
|
} else if (this._identity) {
|
|
5751
|
-
address0 = this._identity.
|
|
5921
|
+
address0 = this._identity.l1Address;
|
|
5752
5922
|
}
|
|
5753
5923
|
} catch {
|
|
5754
5924
|
}
|
|
@@ -5795,8 +5965,8 @@ var Sphere = class _Sphere {
|
|
|
5795
5965
|
} catch {
|
|
5796
5966
|
if (i === 0 && this._identity) {
|
|
5797
5967
|
addresses.push({
|
|
5798
|
-
address: this._identity.
|
|
5799
|
-
publicKey: this._identity.
|
|
5968
|
+
address: this._identity.l1Address,
|
|
5969
|
+
publicKey: this._identity.chainPubkey,
|
|
5800
5970
|
path: this.getDefaultAddressPath(),
|
|
5801
5971
|
index: 0
|
|
5802
5972
|
});
|
|
@@ -5875,7 +6045,7 @@ var Sphere = class _Sphere {
|
|
|
5875
6045
|
} catch {
|
|
5876
6046
|
if (i === 0 && this._identity) {
|
|
5877
6047
|
addresses.push({
|
|
5878
|
-
address: this._identity.
|
|
6048
|
+
address: this._identity.l1Address,
|
|
5879
6049
|
path: this.getDefaultAddressPath(),
|
|
5880
6050
|
index: 0,
|
|
5881
6051
|
isChange: false
|
|
@@ -6229,9 +6399,9 @@ var Sphere = class _Sphere {
|
|
|
6229
6399
|
const nametag = this._addressNametags.get(index);
|
|
6230
6400
|
this._identity = {
|
|
6231
6401
|
privateKey: addressInfo.privateKey,
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
predicateAddress,
|
|
6402
|
+
chainPubkey: addressInfo.publicKey,
|
|
6403
|
+
l1Address: addressInfo.address,
|
|
6404
|
+
directAddress: predicateAddress,
|
|
6235
6405
|
ipnsName: "12D3KooW" + ipnsHash,
|
|
6236
6406
|
nametag
|
|
6237
6407
|
};
|
|
@@ -6244,13 +6414,13 @@ var Sphere = class _Sphere {
|
|
|
6244
6414
|
}
|
|
6245
6415
|
await this.reinitializeModulesForNewAddress();
|
|
6246
6416
|
this.emitEvent("identity:changed", {
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6417
|
+
l1Address: this._identity.l1Address,
|
|
6418
|
+
directAddress: this._identity.directAddress,
|
|
6419
|
+
chainPubkey: this._identity.chainPubkey,
|
|
6250
6420
|
nametag: this._identity.nametag,
|
|
6251
6421
|
addressIndex: index
|
|
6252
6422
|
});
|
|
6253
|
-
console.log(`[Sphere] Switched to address ${index}:`, this._identity.
|
|
6423
|
+
console.log(`[Sphere] Switched to address ${index}:`, this._identity.l1Address);
|
|
6254
6424
|
}
|
|
6255
6425
|
/**
|
|
6256
6426
|
* Re-initialize modules after address switch
|
|
@@ -6308,7 +6478,7 @@ var Sphere = class _Sphere {
|
|
|
6308
6478
|
);
|
|
6309
6479
|
return {
|
|
6310
6480
|
...info,
|
|
6311
|
-
address:
|
|
6481
|
+
address: publicKeyToAddress(info.publicKey, "alpha")
|
|
6312
6482
|
};
|
|
6313
6483
|
}
|
|
6314
6484
|
/**
|
|
@@ -6335,11 +6505,10 @@ var Sphere = class _Sphere {
|
|
|
6335
6505
|
path
|
|
6336
6506
|
);
|
|
6337
6507
|
const publicKey = getPublicKey(derived.privateKey);
|
|
6338
|
-
const addressHash = hash160(publicKey);
|
|
6339
6508
|
return {
|
|
6340
6509
|
privateKey: derived.privateKey,
|
|
6341
6510
|
publicKey,
|
|
6342
|
-
address:
|
|
6511
|
+
address: publicKeyToAddress(publicKey, "alpha"),
|
|
6343
6512
|
path,
|
|
6344
6513
|
index
|
|
6345
6514
|
};
|
|
@@ -6427,6 +6596,17 @@ var Sphere = class _Sphere {
|
|
|
6427
6596
|
hasNametag() {
|
|
6428
6597
|
return !!this._identity?.nametag;
|
|
6429
6598
|
}
|
|
6599
|
+
/**
|
|
6600
|
+
* Get the PROXY address for the current nametag
|
|
6601
|
+
* PROXY addresses are derived from the nametag hash and require
|
|
6602
|
+
* the nametag token to claim funds sent to them
|
|
6603
|
+
* @returns PROXY address string or undefined if no nametag
|
|
6604
|
+
*/
|
|
6605
|
+
getProxyAddress() {
|
|
6606
|
+
const nametag = this._identity?.nametag;
|
|
6607
|
+
if (!nametag) return void 0;
|
|
6608
|
+
return `PROXY:${hashNametag(nametag)}`;
|
|
6609
|
+
}
|
|
6430
6610
|
/**
|
|
6431
6611
|
* Register a nametag for the current active address
|
|
6432
6612
|
* Each address can have its own independent nametag
|
|
@@ -6455,7 +6635,11 @@ var Sphere = class _Sphere {
|
|
|
6455
6635
|
throw new Error(`Nametag already registered for address ${this._currentAddressIndex}: @${this._identity.nametag}`);
|
|
6456
6636
|
}
|
|
6457
6637
|
if (this._transport.registerNametag) {
|
|
6458
|
-
const success = await this._transport.registerNametag(
|
|
6638
|
+
const success = await this._transport.registerNametag(
|
|
6639
|
+
cleanNametag,
|
|
6640
|
+
this._identity.chainPubkey,
|
|
6641
|
+
this._identity.directAddress || ""
|
|
6642
|
+
);
|
|
6459
6643
|
if (!success) {
|
|
6460
6644
|
throw new Error("Failed to register nametag. It may already be taken.");
|
|
6461
6645
|
}
|
|
@@ -6549,7 +6733,11 @@ var Sphere = class _Sphere {
|
|
|
6549
6733
|
return;
|
|
6550
6734
|
}
|
|
6551
6735
|
try {
|
|
6552
|
-
const success = await this._transport.registerNametag(
|
|
6736
|
+
const success = await this._transport.registerNametag(
|
|
6737
|
+
nametag,
|
|
6738
|
+
this._identity.chainPubkey,
|
|
6739
|
+
this._identity.directAddress || ""
|
|
6740
|
+
);
|
|
6553
6741
|
if (success) {
|
|
6554
6742
|
console.log(`[Sphere] Nametag @${nametag} synced with Nostr`);
|
|
6555
6743
|
} else {
|
|
@@ -6559,6 +6747,38 @@ var Sphere = class _Sphere {
|
|
|
6559
6747
|
console.warn(`[Sphere] Nametag sync failed:`, error);
|
|
6560
6748
|
}
|
|
6561
6749
|
}
|
|
6750
|
+
/**
|
|
6751
|
+
* Recover nametag from Nostr after wallet import
|
|
6752
|
+
* Searches for encrypted nametag events authored by this wallet's pubkey
|
|
6753
|
+
* and decrypts them to restore the nametag association
|
|
6754
|
+
*/
|
|
6755
|
+
async recoverNametagFromNostr() {
|
|
6756
|
+
if (this._identity?.nametag) {
|
|
6757
|
+
return;
|
|
6758
|
+
}
|
|
6759
|
+
if (!this._transport.recoverNametag) {
|
|
6760
|
+
return;
|
|
6761
|
+
}
|
|
6762
|
+
try {
|
|
6763
|
+
const recoveredNametag = await this._transport.recoverNametag();
|
|
6764
|
+
if (recoveredNametag) {
|
|
6765
|
+
if (this._identity) {
|
|
6766
|
+
this._identity.nametag = recoveredNametag;
|
|
6767
|
+
}
|
|
6768
|
+
this._addressNametags.set(this._currentAddressIndex, recoveredNametag);
|
|
6769
|
+
await this._storage.set(STORAGE_KEYS.NAMETAG, recoveredNametag);
|
|
6770
|
+
if (this._transport.registerNametag) {
|
|
6771
|
+
await this._transport.registerNametag(
|
|
6772
|
+
recoveredNametag,
|
|
6773
|
+
this._identity.chainPubkey,
|
|
6774
|
+
this._identity.directAddress || ""
|
|
6775
|
+
);
|
|
6776
|
+
}
|
|
6777
|
+
this.emitEvent("nametag:recovered", { nametag: recoveredNametag });
|
|
6778
|
+
}
|
|
6779
|
+
} catch {
|
|
6780
|
+
}
|
|
6781
|
+
}
|
|
6562
6782
|
/**
|
|
6563
6783
|
* Validate nametag format
|
|
6564
6784
|
*/
|
|
@@ -6685,57 +6905,64 @@ var Sphere = class _Sphere {
|
|
|
6685
6905
|
const nametag = this._addressNametags.get(this._currentAddressIndex);
|
|
6686
6906
|
this._identity = {
|
|
6687
6907
|
privateKey: addressInfo.privateKey,
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
predicateAddress,
|
|
6908
|
+
chainPubkey: addressInfo.publicKey,
|
|
6909
|
+
l1Address: addressInfo.address,
|
|
6910
|
+
directAddress: predicateAddress,
|
|
6691
6911
|
ipnsName: "12D3KooW" + ipnsHash,
|
|
6692
6912
|
nametag
|
|
6693
6913
|
};
|
|
6694
6914
|
this._storage.setIdentity(this._identity);
|
|
6695
|
-
console.log(`[Sphere] Restored to address ${this._currentAddressIndex}:`, this._identity.
|
|
6915
|
+
console.log(`[Sphere] Restored to address ${this._currentAddressIndex}:`, this._identity.l1Address);
|
|
6696
6916
|
} else {
|
|
6697
6917
|
if (savedNametag && this._identity) {
|
|
6698
|
-
|
|
6918
|
+
let nametag = savedNametag;
|
|
6919
|
+
if (savedNametag.startsWith("{")) {
|
|
6920
|
+
try {
|
|
6921
|
+
const parsed = JSON.parse(savedNametag);
|
|
6922
|
+
nametag = parsed["0"] || parsed[0] || Object.values(parsed)[0];
|
|
6923
|
+
} catch {
|
|
6924
|
+
}
|
|
6925
|
+
}
|
|
6926
|
+
this._identity.nametag = nametag;
|
|
6699
6927
|
if (!this._addressNametags.has(0)) {
|
|
6700
|
-
this._addressNametags.set(0,
|
|
6928
|
+
this._addressNametags.set(0, nametag);
|
|
6701
6929
|
}
|
|
6702
|
-
console.log("[Sphere] Restored nametag:", savedNametag);
|
|
6703
6930
|
} else if (this._identity) {
|
|
6704
6931
|
const nametag = this._addressNametags.get(0);
|
|
6705
6932
|
if (nametag) {
|
|
6706
6933
|
this._identity.nametag = nametag;
|
|
6707
|
-
console.log("[Sphere] Restored nametag from map:", nametag);
|
|
6708
6934
|
}
|
|
6709
6935
|
}
|
|
6710
6936
|
}
|
|
6711
6937
|
}
|
|
6712
6938
|
async initializeIdentityFromMnemonic(mnemonic, derivationPath) {
|
|
6713
|
-
const
|
|
6939
|
+
const basePath = derivationPath ?? DEFAULT_BASE_PATH;
|
|
6940
|
+
const fullPath = `${basePath}/0/0`;
|
|
6714
6941
|
const masterKey = identityFromMnemonicSync(mnemonic);
|
|
6715
6942
|
const derivedKey = deriveKeyAtPath(
|
|
6716
6943
|
masterKey.privateKey,
|
|
6717
6944
|
masterKey.chainCode,
|
|
6718
|
-
|
|
6945
|
+
fullPath
|
|
6719
6946
|
);
|
|
6720
6947
|
const publicKey = getPublicKey(derivedKey.privateKey);
|
|
6721
|
-
const
|
|
6948
|
+
const address = publicKeyToAddress(publicKey, "alpha");
|
|
6722
6949
|
const ipnsHash = sha256(publicKey, "hex").slice(0, 40);
|
|
6723
6950
|
const predicateAddress = await deriveL3PredicateAddress(derivedKey.privateKey);
|
|
6724
6951
|
this._identity = {
|
|
6725
6952
|
privateKey: derivedKey.privateKey,
|
|
6726
|
-
publicKey,
|
|
6727
|
-
|
|
6728
|
-
predicateAddress,
|
|
6953
|
+
chainPubkey: publicKey,
|
|
6954
|
+
l1Address: address,
|
|
6955
|
+
directAddress: predicateAddress,
|
|
6729
6956
|
ipnsName: "12D3KooW" + ipnsHash
|
|
6730
6957
|
};
|
|
6731
6958
|
this._masterKey = masterKey;
|
|
6732
|
-
console.log("[Sphere] Identity initialized from mnemonic, path:", path);
|
|
6733
6959
|
}
|
|
6734
6960
|
async initializeIdentityFromMasterKey(masterKey, chainCode, derivationPath) {
|
|
6735
|
-
const
|
|
6961
|
+
const basePath = derivationPath ?? DEFAULT_BASE_PATH;
|
|
6962
|
+
const fullPath = `${basePath}/0/0`;
|
|
6736
6963
|
let privateKey;
|
|
6737
6964
|
if (chainCode) {
|
|
6738
|
-
const derivedKey = deriveKeyAtPath(masterKey, chainCode,
|
|
6965
|
+
const derivedKey = deriveKeyAtPath(masterKey, chainCode, fullPath);
|
|
6739
6966
|
privateKey = derivedKey.privateKey;
|
|
6740
6967
|
this._masterKey = {
|
|
6741
6968
|
privateKey: masterKey,
|
|
@@ -6746,17 +6973,16 @@ var Sphere = class _Sphere {
|
|
|
6746
6973
|
this._masterKey = null;
|
|
6747
6974
|
}
|
|
6748
6975
|
const publicKey = getPublicKey(privateKey);
|
|
6749
|
-
const
|
|
6976
|
+
const address = publicKeyToAddress(publicKey, "alpha");
|
|
6750
6977
|
const ipnsHash = sha256(publicKey, "hex").slice(0, 40);
|
|
6751
6978
|
const predicateAddress = await deriveL3PredicateAddress(privateKey);
|
|
6752
6979
|
this._identity = {
|
|
6753
6980
|
privateKey,
|
|
6754
|
-
publicKey,
|
|
6755
|
-
|
|
6756
|
-
predicateAddress,
|
|
6981
|
+
chainPubkey: publicKey,
|
|
6982
|
+
l1Address: address,
|
|
6983
|
+
directAddress: predicateAddress,
|
|
6757
6984
|
ipnsName: "12D3KooW" + ipnsHash
|
|
6758
6985
|
};
|
|
6759
|
-
console.log("[Sphere] Identity initialized from master key, path:", path, "chainCode:", !!chainCode);
|
|
6760
6986
|
}
|
|
6761
6987
|
// ===========================================================================
|
|
6762
6988
|
// Private: Provider & Module Initialization
|