decane-connect-kit 2.3.1 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +126 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -2
- package/dist/index.d.ts +62 -2
- package/dist/index.js +121 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1964,7 +1964,7 @@ function createDecane(config) {
|
|
|
1964
1964
|
}
|
|
1965
1965
|
|
|
1966
1966
|
// src/social/client.ts
|
|
1967
|
-
var
|
|
1967
|
+
var import_ethers3 = require("ethers");
|
|
1968
1968
|
var import_web32 = require("@solana/web3.js");
|
|
1969
1969
|
init_errors();
|
|
1970
1970
|
|
|
@@ -2059,10 +2059,26 @@ var ApiClient = class {
|
|
|
2059
2059
|
iv: bytesToB64(share.iv),
|
|
2060
2060
|
wrappedShareMeta: btoa(JSON.stringify(share.wrappedShareMeta)),
|
|
2061
2061
|
evmAddress: share.evmAddress,
|
|
2062
|
-
solanaAddress: share.solanaAddress
|
|
2062
|
+
solanaAddress: share.solanaAddress,
|
|
2063
|
+
tronAddress: share.tronAddress
|
|
2063
2064
|
})
|
|
2064
2065
|
});
|
|
2065
2066
|
}
|
|
2067
|
+
// ── Transaction history ───────────────────────────────────────────────────
|
|
2068
|
+
async recordTransaction(jwt, tx) {
|
|
2069
|
+
const body = await this._request("/transactions", {
|
|
2070
|
+
method: "POST",
|
|
2071
|
+
headers: { Authorization: `Bearer ${jwt}` },
|
|
2072
|
+
body: JSON.stringify(tx)
|
|
2073
|
+
});
|
|
2074
|
+
return body.transaction;
|
|
2075
|
+
}
|
|
2076
|
+
async getTransactions(jwt, limit = 50) {
|
|
2077
|
+
const body = await this._request(`/transactions?limit=${encodeURIComponent(String(limit))}`, {
|
|
2078
|
+
headers: { Authorization: `Bearer ${jwt}` }
|
|
2079
|
+
});
|
|
2080
|
+
return body.transactions;
|
|
2081
|
+
}
|
|
2066
2082
|
// ── WebAuthn registration (additive to the PRF-only passkey flow) ─────────
|
|
2067
2083
|
async getWebAuthnRegisterOptions(jwt, rpId, rpName) {
|
|
2068
2084
|
return this._request(`/webauthn/register-options?rpId=${encodeURIComponent(rpId)}&rpName=${encodeURIComponent(rpName)}`, {
|
|
@@ -2200,6 +2216,9 @@ var Storage = class {
|
|
|
2200
2216
|
}
|
|
2201
2217
|
};
|
|
2202
2218
|
|
|
2219
|
+
// src/social/session.ts
|
|
2220
|
+
var import_ethers = require("ethers");
|
|
2221
|
+
|
|
2203
2222
|
// src/social/teeClient.ts
|
|
2204
2223
|
var import_browser = require("@simplewebauthn/browser");
|
|
2205
2224
|
|
|
@@ -2480,6 +2499,11 @@ var TeeClient = class {
|
|
|
2480
2499
|
|
|
2481
2500
|
// src/social/session.ts
|
|
2482
2501
|
init_errors();
|
|
2502
|
+
function evmToTronAddress(evmAddress) {
|
|
2503
|
+
const hex41 = "41" + evmAddress.toLowerCase().replace(/^0x/, "");
|
|
2504
|
+
const checksum = (0, import_ethers.sha256)((0, import_ethers.sha256)("0x" + hex41)).slice(2, 10);
|
|
2505
|
+
return (0, import_ethers.encodeBase58)("0x" + hex41 + checksum);
|
|
2506
|
+
}
|
|
2483
2507
|
var SessionManager = class {
|
|
2484
2508
|
constructor(events, durationMs, teeUrl, requireAssertionPerSignature = false) {
|
|
2485
2509
|
this.events = events;
|
|
@@ -2489,6 +2513,7 @@ var SessionManager = class {
|
|
|
2489
2513
|
this.tee = null;
|
|
2490
2514
|
this.evmAddress = null;
|
|
2491
2515
|
this.solanaAddress = null;
|
|
2516
|
+
this.tronAddress = null;
|
|
2492
2517
|
this.expiresAt = null;
|
|
2493
2518
|
this.timeoutId = null;
|
|
2494
2519
|
}
|
|
@@ -2515,6 +2540,7 @@ var SessionManager = class {
|
|
|
2515
2540
|
this.tee.adoptHandle(handle, this.requireAssertionPerSignature);
|
|
2516
2541
|
this.evmAddress = addresses.evm;
|
|
2517
2542
|
this.solanaAddress = addresses.solana;
|
|
2543
|
+
this.tronAddress = addresses.tron ?? evmToTronAddress(addresses.evm);
|
|
2518
2544
|
this.expiresAt = expiresAtMs;
|
|
2519
2545
|
this.setExpiryTimer(expiresAtMs - Date.now());
|
|
2520
2546
|
this.events.emit("session-started");
|
|
@@ -2541,15 +2567,17 @@ var SessionManager = class {
|
|
|
2541
2567
|
"requireAssertionPerSignature was requested but this signer does not support it \u2014 refusing to open a session with weaker authority than configured."
|
|
2542
2568
|
);
|
|
2543
2569
|
}
|
|
2544
|
-
const
|
|
2545
|
-
if (!
|
|
2570
|
+
const resolved = verified ?? fallback;
|
|
2571
|
+
if (!resolved) {
|
|
2546
2572
|
this.tee = null;
|
|
2547
2573
|
throw new Error(
|
|
2548
2574
|
"No addresses available for this wallet \u2014 the signer could not derive them and none are recorded"
|
|
2549
2575
|
);
|
|
2550
2576
|
}
|
|
2577
|
+
const addresses = { evm: resolved.evm, solana: resolved.solana, tron: resolved.tron ?? evmToTronAddress(resolved.evm) };
|
|
2551
2578
|
this.evmAddress = addresses.evm;
|
|
2552
2579
|
this.solanaAddress = addresses.solana;
|
|
2580
|
+
this.tronAddress = addresses.tron;
|
|
2553
2581
|
const serverTtlMs = this.tee.sessionExpiresIn();
|
|
2554
2582
|
const effectiveMs = serverTtlMs != null ? Math.min(this.durationMs, serverTtlMs * 1e3) : this.durationMs;
|
|
2555
2583
|
this.expiresAt = Date.now() + effectiveMs;
|
|
@@ -2566,6 +2594,7 @@ var SessionManager = class {
|
|
|
2566
2594
|
this.tee = null;
|
|
2567
2595
|
this.evmAddress = null;
|
|
2568
2596
|
this.solanaAddress = null;
|
|
2597
|
+
this.tronAddress = null;
|
|
2569
2598
|
this.expiresAt = null;
|
|
2570
2599
|
if (this.timeoutId) {
|
|
2571
2600
|
clearTimeout(this.timeoutId);
|
|
@@ -2584,7 +2613,11 @@ var SessionManager = class {
|
|
|
2584
2613
|
}
|
|
2585
2614
|
addresses() {
|
|
2586
2615
|
if (!this.evmAddress || !this.solanaAddress) return null;
|
|
2587
|
-
return {
|
|
2616
|
+
return {
|
|
2617
|
+
evm: this.evmAddress,
|
|
2618
|
+
solana: this.solanaAddress,
|
|
2619
|
+
tron: this.tronAddress ?? evmToTronAddress(this.evmAddress)
|
|
2620
|
+
};
|
|
2588
2621
|
}
|
|
2589
2622
|
};
|
|
2590
2623
|
|
|
@@ -2767,12 +2800,12 @@ async function verifyEmailCode(api, email, code) {
|
|
|
2767
2800
|
}
|
|
2768
2801
|
|
|
2769
2802
|
// src/social/signers/evm.ts
|
|
2770
|
-
var
|
|
2803
|
+
var import_ethers2 = require("ethers");
|
|
2771
2804
|
async function signEvmTransaction(tee, chain, tx, jwt) {
|
|
2772
|
-
const resolved = await (0,
|
|
2773
|
-
const unsigned =
|
|
2805
|
+
const resolved = await (0, import_ethers2.resolveProperties)(tx);
|
|
2806
|
+
const unsigned = import_ethers2.Transaction.from(resolved).unsignedSerialized;
|
|
2774
2807
|
const payload = unsigned.startsWith("0x") ? unsigned.slice(2) : unsigned;
|
|
2775
|
-
const txHash = (0,
|
|
2808
|
+
const txHash = (0, import_ethers2.keccak256)("0x" + payload);
|
|
2776
2809
|
return tee.sign({ chain, kind: "transaction", payload, txHash }, jwt);
|
|
2777
2810
|
}
|
|
2778
2811
|
async function signEvmMessage(tee, chain, message, jwt) {
|
|
@@ -3437,9 +3470,11 @@ async function createDecaneConnect(config) {
|
|
|
3437
3470
|
let shareSet;
|
|
3438
3471
|
let evmAddress;
|
|
3439
3472
|
let solanaAddress;
|
|
3473
|
+
let tronAddress;
|
|
3440
3474
|
try {
|
|
3441
|
-
evmAddress = new
|
|
3475
|
+
evmAddress = new import_ethers3.Wallet(toHex2(master)).address;
|
|
3442
3476
|
solanaAddress = import_web32.Keypair.fromSeed(master).publicKey.toBase58();
|
|
3477
|
+
tronAddress = evmToTronAddress2(evmAddress);
|
|
3443
3478
|
shareSet = await splitMaster(master, 1);
|
|
3444
3479
|
} finally {
|
|
3445
3480
|
zeroize(master);
|
|
@@ -3470,10 +3505,11 @@ async function createDecaneConnect(config) {
|
|
|
3470
3505
|
// credential IDs, prfSalt, pinSalt stay on-device — never sent to server
|
|
3471
3506
|
},
|
|
3472
3507
|
evmAddress,
|
|
3473
|
-
solanaAddress
|
|
3508
|
+
solanaAddress,
|
|
3509
|
+
tronAddress
|
|
3474
3510
|
});
|
|
3475
3511
|
zeroize(shareSet.server);
|
|
3476
|
-
const addresses = { evm: evmAddress, solana: solanaAddress };
|
|
3512
|
+
const addresses = { evm: evmAddress, solana: solanaAddress, tron: tronAddress };
|
|
3477
3513
|
if (unlockMethod === "passkey" && meta.credentialId && meta.prfSalt) {
|
|
3478
3514
|
try {
|
|
3479
3515
|
await api.putRecoveryBackup(jwt, {
|
|
@@ -3496,6 +3532,7 @@ async function createDecaneConnect(config) {
|
|
|
3496
3532
|
}
|
|
3497
3533
|
addresses.evm = evmAddress = confirmed.evm;
|
|
3498
3534
|
addresses.solana = solanaAddress = confirmed.solana;
|
|
3535
|
+
addresses.tron = tronAddress = confirmed.tron ?? evmToTronAddress2(confirmed.evm);
|
|
3499
3536
|
if (config.offerRecoveryAtSignup !== false && config.onRecoveryShareOffer) {
|
|
3500
3537
|
try {
|
|
3501
3538
|
const choice = await config.onRecoveryShareOffer({ evmAddress, solanaAddress });
|
|
@@ -3519,7 +3556,7 @@ async function createDecaneConnect(config) {
|
|
|
3519
3556
|
}
|
|
3520
3557
|
async function returningUserUnlock(userId, jwt) {
|
|
3521
3558
|
const rawAddresses = await api.getAddresses(jwt);
|
|
3522
|
-
const recordedAddresses = rawAddresses.evm && rawAddresses.solana ? { evm: rawAddresses.evm, solana: rawAddresses.solana } : null;
|
|
3559
|
+
const recordedAddresses = rawAddresses.evm && rawAddresses.solana ? { evm: rawAddresses.evm, solana: rawAddresses.solana, tron: rawAddresses.tron ?? evmToTronAddress2(rawAddresses.evm) } : null;
|
|
3523
3560
|
const stored = await storage.getShare(userId);
|
|
3524
3561
|
let deviceShare;
|
|
3525
3562
|
if (!stored) {
|
|
@@ -3601,7 +3638,7 @@ async function createDecaneConnect(config) {
|
|
|
3601
3638
|
throw new ShareCorruptedError();
|
|
3602
3639
|
}
|
|
3603
3640
|
const rawAddresses = await api.getAddresses(result.jwt);
|
|
3604
|
-
const recordedAddresses = rawAddresses.evm && rawAddresses.solana ? { evm: rawAddresses.evm, solana: rawAddresses.solana } : null;
|
|
3641
|
+
const recordedAddresses = rawAddresses.evm && rawAddresses.solana ? { evm: rawAddresses.evm, solana: rawAddresses.solana, tron: rawAddresses.tron ?? evmToTronAddress2(rawAddresses.evm) } : null;
|
|
3605
3642
|
const addresses = await session.start(deviceShare, result.jwt, recordedAddresses);
|
|
3606
3643
|
zeroize(deviceShare);
|
|
3607
3644
|
auth = { jwt: result.jwt, userId, addresses };
|
|
@@ -3733,6 +3770,10 @@ async function createDecaneConnect(config) {
|
|
|
3733
3770
|
const sig = await signSolanaMessage(tee, req.chain, msg, auth?.jwt);
|
|
3734
3771
|
return bufferToB64u(sig);
|
|
3735
3772
|
}
|
|
3773
|
+
if (req.chain.startsWith("tron:")) {
|
|
3774
|
+
const msg = typeof req.message === "string" ? req.message : new TextDecoder().decode(req.message);
|
|
3775
|
+
return tee.sign({ chain: req.chain, kind: "message", payload: msg }, auth?.jwt);
|
|
3776
|
+
}
|
|
3736
3777
|
throw new CallSequenceError(`Unsupported chain: ${req.chain}`);
|
|
3737
3778
|
},
|
|
3738
3779
|
async sendTransaction(req) {
|
|
@@ -3780,6 +3821,16 @@ async function createDecaneConnect(config) {
|
|
|
3780
3821
|
};
|
|
3781
3822
|
const signedTx = await signEvmTransaction(tee, req.chain, tx, auth?.jwt);
|
|
3782
3823
|
const txResponse = await provider.broadcastTransaction(signedTx);
|
|
3824
|
+
if (auth?.jwt) {
|
|
3825
|
+
void api.recordTransaction(auth.jwt, {
|
|
3826
|
+
chain: req.chain,
|
|
3827
|
+
txHash: txResponse.hash,
|
|
3828
|
+
to: req.to,
|
|
3829
|
+
value: (req.value ?? 0n).toString(),
|
|
3830
|
+
kind: "send"
|
|
3831
|
+
}).catch(() => {
|
|
3832
|
+
});
|
|
3833
|
+
}
|
|
3783
3834
|
return txResponse.hash;
|
|
3784
3835
|
},
|
|
3785
3836
|
async signTypedData(req) {
|
|
@@ -3812,6 +3863,14 @@ async function createDecaneConnect(config) {
|
|
|
3812
3863
|
getAccessToken() {
|
|
3813
3864
|
return auth?.jwt ?? null;
|
|
3814
3865
|
},
|
|
3866
|
+
async recordTransaction(tx) {
|
|
3867
|
+
if (!auth?.jwt) throw new CallSequenceError("Not connected \u2014 call connect() first");
|
|
3868
|
+
return api.recordTransaction(auth.jwt, tx);
|
|
3869
|
+
},
|
|
3870
|
+
async getTransactionHistory(limit = 50) {
|
|
3871
|
+
if (!auth?.jwt) throw new CallSequenceError("Not connected \u2014 call connect() first");
|
|
3872
|
+
return api.getTransactions(auth.jwt, limit);
|
|
3873
|
+
},
|
|
3815
3874
|
getEthereumProvider(opts) {
|
|
3816
3875
|
if (!ethProvider) {
|
|
3817
3876
|
const firstEvm = config.chains.find((c) => c.startsWith("evm:"));
|
|
@@ -3834,6 +3893,14 @@ async function createDecaneConnect(config) {
|
|
|
3834
3893
|
const solChain = config.chains.find((c) => c.startsWith("solana:")) ?? "solana:mainnet";
|
|
3835
3894
|
return signSolanaTransaction(tee, solChain, tx, auth?.jwt);
|
|
3836
3895
|
},
|
|
3896
|
+
async signTronTransaction(rawDataHex) {
|
|
3897
|
+
const tee = session.requireActive();
|
|
3898
|
+
const tronChain = config.chains.find((c) => c.startsWith("tron:")) ?? "tron:mainnet";
|
|
3899
|
+
return tee.sign(
|
|
3900
|
+
{ chain: tronChain, kind: "transaction", payload: rawDataHex.replace(/^0x/, "") },
|
|
3901
|
+
auth?.jwt
|
|
3902
|
+
);
|
|
3903
|
+
},
|
|
3837
3904
|
async disconnect() {
|
|
3838
3905
|
session.end();
|
|
3839
3906
|
if (auth?.jwt) {
|
|
@@ -3989,12 +4056,19 @@ function b64uToBuffer(b64u) {
|
|
|
3989
4056
|
function toHex2(bytes) {
|
|
3990
4057
|
return "0x" + Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3991
4058
|
}
|
|
4059
|
+
function evmToTronAddress2(evmAddress) {
|
|
4060
|
+
const hex41 = "41" + evmAddress.toLowerCase().replace(/^0x/, "");
|
|
4061
|
+
const checksum = (0, import_ethers3.sha256)((0, import_ethers3.sha256)("0x" + hex41)).slice(2, 10);
|
|
4062
|
+
return (0, import_ethers3.encodeBase58)("0x" + hex41 + checksum);
|
|
4063
|
+
}
|
|
3992
4064
|
async function deriveAddressesFromShares(a, b) {
|
|
3993
4065
|
const master = await combineShares(a, b);
|
|
3994
4066
|
try {
|
|
4067
|
+
const evm = new import_ethers3.Wallet(toHex2(master)).address;
|
|
3995
4068
|
return {
|
|
3996
|
-
evm
|
|
3997
|
-
solana: import_web32.Keypair.fromSeed(master).publicKey.toBase58()
|
|
4069
|
+
evm,
|
|
4070
|
+
solana: import_web32.Keypair.fromSeed(master).publicKey.toBase58(),
|
|
4071
|
+
tron: evmToTronAddress2(evm)
|
|
3998
4072
|
};
|
|
3999
4073
|
} finally {
|
|
4000
4074
|
zeroize(master);
|
|
@@ -6009,6 +6083,21 @@ function DecaneKit({ config, children }) {
|
|
|
6009
6083
|
if (!sdk) throw new Error("Social wallet not connected");
|
|
6010
6084
|
return sdk.signSolanaTransaction(tx);
|
|
6011
6085
|
}, []);
|
|
6086
|
+
const socialSignTronTransaction = (0, import_react5.useCallback)(async (rawDataHex) => {
|
|
6087
|
+
const sdk = socialRef.current;
|
|
6088
|
+
if (!sdk) throw new Error("Social wallet not connected");
|
|
6089
|
+
return sdk.signTronTransaction(rawDataHex);
|
|
6090
|
+
}, []);
|
|
6091
|
+
const socialRecordTransaction = (0, import_react5.useCallback)(async (tx) => {
|
|
6092
|
+
const sdk = socialRef.current;
|
|
6093
|
+
if (!sdk) throw new Error("Social wallet not connected");
|
|
6094
|
+
return sdk.recordTransaction(tx);
|
|
6095
|
+
}, []);
|
|
6096
|
+
const socialGetTransactionHistory = (0, import_react5.useCallback)(async (limit) => {
|
|
6097
|
+
const sdk = socialRef.current;
|
|
6098
|
+
if (!sdk) throw new Error("Social wallet not connected");
|
|
6099
|
+
return sdk.getTransactionHistory(limit);
|
|
6100
|
+
}, []);
|
|
6012
6101
|
const socialSignTypedData = (0, import_react5.useCallback)(async (req) => {
|
|
6013
6102
|
const sdk = socialRef.current;
|
|
6014
6103
|
if (!sdk) throw new Error("Social wallet not connected");
|
|
@@ -6099,6 +6188,9 @@ function DecaneKit({ config, children }) {
|
|
|
6099
6188
|
socialGetBalances,
|
|
6100
6189
|
socialGetEthereumProvider,
|
|
6101
6190
|
socialSignAuthorization,
|
|
6191
|
+
socialSignTronTransaction,
|
|
6192
|
+
socialRecordTransaction,
|
|
6193
|
+
socialGetTransactionHistory,
|
|
6102
6194
|
socialGetAccessToken,
|
|
6103
6195
|
socialSignSolanaTransaction,
|
|
6104
6196
|
socialSignTypedData,
|
|
@@ -6319,6 +6411,9 @@ function useSocialWallet() {
|
|
|
6319
6411
|
socialSignMessage,
|
|
6320
6412
|
socialSendTransaction,
|
|
6321
6413
|
socialSignSolanaTransaction,
|
|
6414
|
+
socialSignTronTransaction,
|
|
6415
|
+
socialRecordTransaction,
|
|
6416
|
+
socialGetTransactionHistory,
|
|
6322
6417
|
socialSignTypedData,
|
|
6323
6418
|
socialGetBalance,
|
|
6324
6419
|
socialGetBalances,
|
|
@@ -6361,6 +6456,18 @@ function useSocialWallet() {
|
|
|
6361
6456
|
(tx) => run(() => socialSignSolanaTransaction(tx)),
|
|
6362
6457
|
[socialSignSolanaTransaction]
|
|
6363
6458
|
);
|
|
6459
|
+
const signTronTransaction = (0, import_react6.useCallback)(
|
|
6460
|
+
(rawDataHex) => run(() => socialSignTronTransaction(rawDataHex)),
|
|
6461
|
+
[socialSignTronTransaction]
|
|
6462
|
+
);
|
|
6463
|
+
const recordTransaction = (0, import_react6.useCallback)(
|
|
6464
|
+
(tx) => run(() => socialRecordTransaction(tx)),
|
|
6465
|
+
[socialRecordTransaction]
|
|
6466
|
+
);
|
|
6467
|
+
const getTransactionHistory = (0, import_react6.useCallback)(
|
|
6468
|
+
(limit) => socialGetTransactionHistory(limit),
|
|
6469
|
+
[socialGetTransactionHistory]
|
|
6470
|
+
);
|
|
6364
6471
|
const signTypedData = (0, import_react6.useCallback)(
|
|
6365
6472
|
(req) => run(() => socialSignTypedData(req)),
|
|
6366
6473
|
[socialSignTypedData]
|
|
@@ -6442,6 +6549,9 @@ function useSocialWallet() {
|
|
|
6442
6549
|
signMessage,
|
|
6443
6550
|
sendTransaction,
|
|
6444
6551
|
signSolanaTransaction: signSolanaTransaction2,
|
|
6552
|
+
signTronTransaction,
|
|
6553
|
+
recordTransaction,
|
|
6554
|
+
getTransactionHistory,
|
|
6445
6555
|
signTypedData,
|
|
6446
6556
|
// Balances (native token; read-only, works while locked)
|
|
6447
6557
|
getBalance,
|