decane-connect-kit 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1964,7 +1964,7 @@ function createDecane(config) {
1964
1964
  }
1965
1965
 
1966
1966
  // src/social/client.ts
1967
- var import_ethers2 = require("ethers");
1967
+ var import_ethers3 = require("ethers");
1968
1968
  var import_web32 = require("@solana/web3.js");
1969
1969
  init_errors();
1970
1970
 
@@ -2059,7 +2059,8 @@ 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
  }
@@ -2200,6 +2201,9 @@ var Storage = class {
2200
2201
  }
2201
2202
  };
2202
2203
 
2204
+ // src/social/session.ts
2205
+ var import_ethers = require("ethers");
2206
+
2203
2207
  // src/social/teeClient.ts
2204
2208
  var import_browser = require("@simplewebauthn/browser");
2205
2209
 
@@ -2480,6 +2484,11 @@ var TeeClient = class {
2480
2484
 
2481
2485
  // src/social/session.ts
2482
2486
  init_errors();
2487
+ function evmToTronAddress(evmAddress) {
2488
+ const hex41 = "41" + evmAddress.toLowerCase().replace(/^0x/, "");
2489
+ const checksum = (0, import_ethers.sha256)((0, import_ethers.sha256)("0x" + hex41)).slice(2, 10);
2490
+ return (0, import_ethers.encodeBase58)("0x" + hex41 + checksum);
2491
+ }
2483
2492
  var SessionManager = class {
2484
2493
  constructor(events, durationMs, teeUrl, requireAssertionPerSignature = false) {
2485
2494
  this.events = events;
@@ -2489,6 +2498,7 @@ var SessionManager = class {
2489
2498
  this.tee = null;
2490
2499
  this.evmAddress = null;
2491
2500
  this.solanaAddress = null;
2501
+ this.tronAddress = null;
2492
2502
  this.expiresAt = null;
2493
2503
  this.timeoutId = null;
2494
2504
  }
@@ -2515,6 +2525,7 @@ var SessionManager = class {
2515
2525
  this.tee.adoptHandle(handle, this.requireAssertionPerSignature);
2516
2526
  this.evmAddress = addresses.evm;
2517
2527
  this.solanaAddress = addresses.solana;
2528
+ this.tronAddress = addresses.tron ?? evmToTronAddress(addresses.evm);
2518
2529
  this.expiresAt = expiresAtMs;
2519
2530
  this.setExpiryTimer(expiresAtMs - Date.now());
2520
2531
  this.events.emit("session-started");
@@ -2541,15 +2552,17 @@ var SessionManager = class {
2541
2552
  "requireAssertionPerSignature was requested but this signer does not support it \u2014 refusing to open a session with weaker authority than configured."
2542
2553
  );
2543
2554
  }
2544
- const addresses = verified ?? fallback;
2545
- if (!addresses) {
2555
+ const resolved = verified ?? fallback;
2556
+ if (!resolved) {
2546
2557
  this.tee = null;
2547
2558
  throw new Error(
2548
2559
  "No addresses available for this wallet \u2014 the signer could not derive them and none are recorded"
2549
2560
  );
2550
2561
  }
2562
+ const addresses = { evm: resolved.evm, solana: resolved.solana, tron: resolved.tron ?? evmToTronAddress(resolved.evm) };
2551
2563
  this.evmAddress = addresses.evm;
2552
2564
  this.solanaAddress = addresses.solana;
2565
+ this.tronAddress = addresses.tron;
2553
2566
  const serverTtlMs = this.tee.sessionExpiresIn();
2554
2567
  const effectiveMs = serverTtlMs != null ? Math.min(this.durationMs, serverTtlMs * 1e3) : this.durationMs;
2555
2568
  this.expiresAt = Date.now() + effectiveMs;
@@ -2566,6 +2579,7 @@ var SessionManager = class {
2566
2579
  this.tee = null;
2567
2580
  this.evmAddress = null;
2568
2581
  this.solanaAddress = null;
2582
+ this.tronAddress = null;
2569
2583
  this.expiresAt = null;
2570
2584
  if (this.timeoutId) {
2571
2585
  clearTimeout(this.timeoutId);
@@ -2584,7 +2598,11 @@ var SessionManager = class {
2584
2598
  }
2585
2599
  addresses() {
2586
2600
  if (!this.evmAddress || !this.solanaAddress) return null;
2587
- return { evm: this.evmAddress, solana: this.solanaAddress };
2601
+ return {
2602
+ evm: this.evmAddress,
2603
+ solana: this.solanaAddress,
2604
+ tron: this.tronAddress ?? evmToTronAddress(this.evmAddress)
2605
+ };
2588
2606
  }
2589
2607
  };
2590
2608
 
@@ -2767,12 +2785,12 @@ async function verifyEmailCode(api, email, code) {
2767
2785
  }
2768
2786
 
2769
2787
  // src/social/signers/evm.ts
2770
- var import_ethers = require("ethers");
2788
+ var import_ethers2 = require("ethers");
2771
2789
  async function signEvmTransaction(tee, chain, tx, jwt) {
2772
- const resolved = await (0, import_ethers.resolveProperties)(tx);
2773
- const unsigned = import_ethers.Transaction.from(resolved).unsignedSerialized;
2790
+ const resolved = await (0, import_ethers2.resolveProperties)(tx);
2791
+ const unsigned = import_ethers2.Transaction.from(resolved).unsignedSerialized;
2774
2792
  const payload = unsigned.startsWith("0x") ? unsigned.slice(2) : unsigned;
2775
- const txHash = (0, import_ethers.keccak256)("0x" + payload);
2793
+ const txHash = (0, import_ethers2.keccak256)("0x" + payload);
2776
2794
  return tee.sign({ chain, kind: "transaction", payload, txHash }, jwt);
2777
2795
  }
2778
2796
  async function signEvmMessage(tee, chain, message, jwt) {
@@ -2787,7 +2805,7 @@ async function signEvmAuthorization(tee, chainId, address, nonce, jwt) {
2787
2805
  const r = "0x" + hex.slice(0, 64);
2788
2806
  const s = "0x" + hex.slice(64, 128);
2789
2807
  const v = parseInt(hex.slice(128, 130), 16);
2790
- return { yParity: v >= 27 ? v - 27 : v, r, s };
2808
+ return { chainId, address, nonce, yParity: v >= 27 ? v - 27 : v, r, s };
2791
2809
  }
2792
2810
  async function signEvmTypedData(tee, chain, typedData, jwt) {
2793
2811
  const payload = JSON.stringify(
@@ -2948,9 +2966,6 @@ function createEthereumProvider(client, opts = {}) {
2948
2966
  }
2949
2967
  case "eth_signAuthorization":
2950
2968
  case "wallet_sign7702Authorization": {
2951
- if (!client.signAuthorization) {
2952
- throw Object.assign(new Error("EIP-7702 is not supported by the connected signer."), { code: 4200 });
2953
- }
2954
2969
  const p = params[0];
2955
2970
  const cid = p.chainId != null ? Number(asBigInt(p.chainId)) : chainId;
2956
2971
  const address = p.address ?? p.contractAddress;
@@ -3440,9 +3455,11 @@ async function createDecaneConnect(config) {
3440
3455
  let shareSet;
3441
3456
  let evmAddress;
3442
3457
  let solanaAddress;
3458
+ let tronAddress;
3443
3459
  try {
3444
- evmAddress = new import_ethers2.Wallet(toHex2(master)).address;
3460
+ evmAddress = new import_ethers3.Wallet(toHex2(master)).address;
3445
3461
  solanaAddress = import_web32.Keypair.fromSeed(master).publicKey.toBase58();
3462
+ tronAddress = evmToTronAddress2(evmAddress);
3446
3463
  shareSet = await splitMaster(master, 1);
3447
3464
  } finally {
3448
3465
  zeroize(master);
@@ -3473,10 +3490,11 @@ async function createDecaneConnect(config) {
3473
3490
  // credential IDs, prfSalt, pinSalt stay on-device — never sent to server
3474
3491
  },
3475
3492
  evmAddress,
3476
- solanaAddress
3493
+ solanaAddress,
3494
+ tronAddress
3477
3495
  });
3478
3496
  zeroize(shareSet.server);
3479
- const addresses = { evm: evmAddress, solana: solanaAddress };
3497
+ const addresses = { evm: evmAddress, solana: solanaAddress, tron: tronAddress };
3480
3498
  if (unlockMethod === "passkey" && meta.credentialId && meta.prfSalt) {
3481
3499
  try {
3482
3500
  await api.putRecoveryBackup(jwt, {
@@ -3499,6 +3517,7 @@ async function createDecaneConnect(config) {
3499
3517
  }
3500
3518
  addresses.evm = evmAddress = confirmed.evm;
3501
3519
  addresses.solana = solanaAddress = confirmed.solana;
3520
+ addresses.tron = tronAddress = confirmed.tron ?? evmToTronAddress2(confirmed.evm);
3502
3521
  if (config.offerRecoveryAtSignup !== false && config.onRecoveryShareOffer) {
3503
3522
  try {
3504
3523
  const choice = await config.onRecoveryShareOffer({ evmAddress, solanaAddress });
@@ -3522,7 +3541,7 @@ async function createDecaneConnect(config) {
3522
3541
  }
3523
3542
  async function returningUserUnlock(userId, jwt) {
3524
3543
  const rawAddresses = await api.getAddresses(jwt);
3525
- const recordedAddresses = rawAddresses.evm && rawAddresses.solana ? { evm: rawAddresses.evm, solana: rawAddresses.solana } : null;
3544
+ const recordedAddresses = rawAddresses.evm && rawAddresses.solana ? { evm: rawAddresses.evm, solana: rawAddresses.solana, tron: rawAddresses.tron ?? evmToTronAddress2(rawAddresses.evm) } : null;
3526
3545
  const stored = await storage.getShare(userId);
3527
3546
  let deviceShare;
3528
3547
  if (!stored) {
@@ -3604,7 +3623,7 @@ async function createDecaneConnect(config) {
3604
3623
  throw new ShareCorruptedError();
3605
3624
  }
3606
3625
  const rawAddresses = await api.getAddresses(result.jwt);
3607
- const recordedAddresses = rawAddresses.evm && rawAddresses.solana ? { evm: rawAddresses.evm, solana: rawAddresses.solana } : null;
3626
+ const recordedAddresses = rawAddresses.evm && rawAddresses.solana ? { evm: rawAddresses.evm, solana: rawAddresses.solana, tron: rawAddresses.tron ?? evmToTronAddress2(rawAddresses.evm) } : null;
3608
3627
  const addresses = await session.start(deviceShare, result.jwt, recordedAddresses);
3609
3628
  zeroize(deviceShare);
3610
3629
  auth = { jwt: result.jwt, userId, addresses };
@@ -3736,6 +3755,10 @@ async function createDecaneConnect(config) {
3736
3755
  const sig = await signSolanaMessage(tee, req.chain, msg, auth?.jwt);
3737
3756
  return bufferToB64u(sig);
3738
3757
  }
3758
+ if (req.chain.startsWith("tron:")) {
3759
+ const msg = typeof req.message === "string" ? req.message : new TextDecoder().decode(req.message);
3760
+ return tee.sign({ chain: req.chain, kind: "message", payload: msg }, auth?.jwt);
3761
+ }
3739
3762
  throw new CallSequenceError(`Unsupported chain: ${req.chain}`);
3740
3763
  },
3741
3764
  async sendTransaction(req) {
@@ -3804,7 +3827,16 @@ async function createDecaneConnect(config) {
3804
3827
  },
3805
3828
  async signAuthorization(req) {
3806
3829
  const tee = session.requireActive();
3807
- return signEvmAuthorization(tee, req.chainId, req.address, req.nonce, auth?.jwt);
3830
+ const delegate = req.address ?? req.contractAddress;
3831
+ if (!delegate) throw new CallSequenceError("signAuthorization requires `address` (the delegate contract).");
3832
+ return signEvmAuthorization(tee, req.chainId, delegate, req.nonce, auth?.jwt);
3833
+ },
3834
+ // The current session's access token (the Decane JWT), for authenticating
3835
+ // the user to your own backend — e.g. a sponsored-bundler proxy. Verify it
3836
+ // server-side against https://backend.decane.app/.well-known/jwks.json.
3837
+ // Null when there is no live session.
3838
+ getAccessToken() {
3839
+ return auth?.jwt ?? null;
3808
3840
  },
3809
3841
  getEthereumProvider(opts) {
3810
3842
  if (!ethProvider) {
@@ -3828,6 +3860,14 @@ async function createDecaneConnect(config) {
3828
3860
  const solChain = config.chains.find((c) => c.startsWith("solana:")) ?? "solana:mainnet";
3829
3861
  return signSolanaTransaction(tee, solChain, tx, auth?.jwt);
3830
3862
  },
3863
+ async signTronTransaction(rawDataHex) {
3864
+ const tee = session.requireActive();
3865
+ const tronChain = config.chains.find((c) => c.startsWith("tron:")) ?? "tron:mainnet";
3866
+ return tee.sign(
3867
+ { chain: tronChain, kind: "transaction", payload: rawDataHex.replace(/^0x/, "") },
3868
+ auth?.jwt
3869
+ );
3870
+ },
3831
3871
  async disconnect() {
3832
3872
  session.end();
3833
3873
  if (auth?.jwt) {
@@ -3983,12 +4023,19 @@ function b64uToBuffer(b64u) {
3983
4023
  function toHex2(bytes) {
3984
4024
  return "0x" + Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
3985
4025
  }
4026
+ function evmToTronAddress2(evmAddress) {
4027
+ const hex41 = "41" + evmAddress.toLowerCase().replace(/^0x/, "");
4028
+ const checksum = (0, import_ethers3.sha256)((0, import_ethers3.sha256)("0x" + hex41)).slice(2, 10);
4029
+ return (0, import_ethers3.encodeBase58)("0x" + hex41 + checksum);
4030
+ }
3986
4031
  async function deriveAddressesFromShares(a, b) {
3987
4032
  const master = await combineShares(a, b);
3988
4033
  try {
4034
+ const evm = new import_ethers3.Wallet(toHex2(master)).address;
3989
4035
  return {
3990
- evm: new import_ethers2.Wallet(toHex2(master)).address,
3991
- solana: import_web32.Keypair.fromSeed(master).publicKey.toBase58()
4036
+ evm,
4037
+ solana: import_web32.Keypair.fromSeed(master).publicKey.toBase58(),
4038
+ tron: evmToTronAddress2(evm)
3992
4039
  };
3993
4040
  } finally {
3994
4041
  zeroize(master);
@@ -6003,6 +6050,11 @@ function DecaneKit({ config, children }) {
6003
6050
  if (!sdk) throw new Error("Social wallet not connected");
6004
6051
  return sdk.signSolanaTransaction(tx);
6005
6052
  }, []);
6053
+ const socialSignTronTransaction = (0, import_react5.useCallback)(async (rawDataHex) => {
6054
+ const sdk = socialRef.current;
6055
+ if (!sdk) throw new Error("Social wallet not connected");
6056
+ return sdk.signTronTransaction(rawDataHex);
6057
+ }, []);
6006
6058
  const socialSignTypedData = (0, import_react5.useCallback)(async (req) => {
6007
6059
  const sdk = socialRef.current;
6008
6060
  if (!sdk) throw new Error("Social wallet not connected");
@@ -6026,6 +6078,9 @@ function DecaneKit({ config, children }) {
6026
6078
  },
6027
6079
  []
6028
6080
  );
6081
+ const socialGetAccessToken = (0, import_react5.useCallback)(() => {
6082
+ return socialRef.current?.getAccessToken() ?? null;
6083
+ }, []);
6029
6084
  const socialGetBalances = (0, import_react5.useCallback)(async () => {
6030
6085
  const sdk = socialRef.current;
6031
6086
  if (!sdk) throw new Error("Social wallet not connected");
@@ -6090,6 +6145,8 @@ function DecaneKit({ config, children }) {
6090
6145
  socialGetBalances,
6091
6146
  socialGetEthereumProvider,
6092
6147
  socialSignAuthorization,
6148
+ socialSignTronTransaction,
6149
+ socialGetAccessToken,
6093
6150
  socialSignSolanaTransaction,
6094
6151
  socialSignTypedData,
6095
6152
  socialRotateShares,
@@ -6309,11 +6366,13 @@ function useSocialWallet() {
6309
6366
  socialSignMessage,
6310
6367
  socialSendTransaction,
6311
6368
  socialSignSolanaTransaction,
6369
+ socialSignTronTransaction,
6312
6370
  socialSignTypedData,
6313
6371
  socialGetBalance,
6314
6372
  socialGetBalances,
6315
6373
  socialGetEthereumProvider,
6316
6374
  socialSignAuthorization,
6375
+ socialGetAccessToken,
6317
6376
  socialRotateShares,
6318
6377
  socialExportPortableBackup,
6319
6378
  socialHasRecoveryShare,
@@ -6350,6 +6409,10 @@ function useSocialWallet() {
6350
6409
  (tx) => run(() => socialSignSolanaTransaction(tx)),
6351
6410
  [socialSignSolanaTransaction]
6352
6411
  );
6412
+ const signTronTransaction = (0, import_react6.useCallback)(
6413
+ (rawDataHex) => run(() => socialSignTronTransaction(rawDataHex)),
6414
+ [socialSignTronTransaction]
6415
+ );
6353
6416
  const signTypedData = (0, import_react6.useCallback)(
6354
6417
  (req) => run(() => socialSignTypedData(req)),
6355
6418
  [socialSignTypedData]
@@ -6431,6 +6494,7 @@ function useSocialWallet() {
6431
6494
  signMessage,
6432
6495
  sendTransaction,
6433
6496
  signSolanaTransaction: signSolanaTransaction2,
6497
+ signTronTransaction,
6434
6498
  signTypedData,
6435
6499
  // Balances (native token; read-only, works while locked)
6436
6500
  getBalance,
@@ -6439,6 +6503,9 @@ function useSocialWallet() {
6439
6503
  signAuthorization,
6440
6504
  // An EIP-1193 provider for viem/wagmi/ethers (memoized).
6441
6505
  getEthereumProvider: socialGetEthereumProvider,
6506
+ // The Decane JWT — authenticate the user to your own backend (bundler proxy,
6507
+ // etc.); verify server-side against backend.decane.app/.well-known/jwks.json.
6508
+ getAccessToken: socialGetAccessToken,
6442
6509
  // Recovery (2-of-3 Shamir share set)
6443
6510
  rotateShares,
6444
6511
  exportPortableBackup,