@getpara/core-sdk 2.19.0 → 2.20.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.
@@ -2096,6 +2096,24 @@ const _ParaCore = class _ParaCore {
2096
2096
  return yield __privateGet(this, _walletService).setUserShare(base64Wallets);
2097
2097
  });
2098
2098
  }
2099
+ /**
2100
+ * Migrate a wallet share to the enclave. The share is ECIES-encrypted before
2101
+ * being sent so the plaintext never leaves the caller's process.
2102
+ */
2103
+ migrateWalletShare(opts) {
2104
+ return __async(this, null, function* () {
2105
+ if (!this.ctx.enclaveClient) {
2106
+ throw new Error("Enclave client not initialized");
2107
+ }
2108
+ const scheme = opts.walletScheme || "DKLS";
2109
+ return this.ctx.enclaveClient.migrateShare({
2110
+ walletId: opts.walletId,
2111
+ userShare: opts.userShare,
2112
+ walletScheme: scheme,
2113
+ secretApiKey: opts.secretApiKey
2114
+ });
2115
+ });
2116
+ }
2099
2117
  getTransactionReviewUrl(transactionId, timeoutMs) {
2100
2118
  return __async(this, null, function* () {
2101
2119
  const authMethods = yield this.supportedUserAuthMethods();
@@ -46,7 +46,7 @@ __export(constants_exports, {
46
46
  TRANSACTION_REVIEW_TIMEOUT_MS: () => TRANSACTION_REVIEW_TIMEOUT_MS
47
47
  });
48
48
  module.exports = __toCommonJS(constants_exports);
49
- const PARA_CORE_VERSION = "2.19.0";
49
+ const PARA_CORE_VERSION = "2.20.0";
50
50
  const PREFIX = "@CAPSULE/";
51
51
  const PARA_PREFIX = "@PARA/";
52
52
  const LOCAL_STORAGE_AUTH_INFO = `${PREFIX}authInfo`;
@@ -268,12 +268,14 @@ class PregenWalletService {
268
268
  const [pregenIdentifierType, pregenIdentifier] = (0, import_user_management_client.toPregenTypeAndId)(pregenId);
269
269
  let keygenRes;
270
270
  switch (walletType) {
271
+ case "STELLAR":
271
272
  case "SOLANA":
272
273
  keygenRes = yield __privateGet(this, _paraCoreInterface).platformUtils.ed25519PreKeygen(
273
274
  __privateGet(this, _paraCoreInterface).ctx,
274
275
  pregenIdentifier,
275
276
  pregenIdentifierType,
276
- __privateGet(this, _paraCoreInterface).retrieveSessionCookie()
277
+ __privateGet(this, _paraCoreInterface).retrieveSessionCookie(),
278
+ walletType
277
279
  );
278
280
  break;
279
281
  default:
@@ -292,7 +294,7 @@ class PregenWalletService {
292
294
  __privateGet(this, _walletService).wallets[walletId] = {
293
295
  id: walletId,
294
296
  signer,
295
- scheme: walletType === "SOLANA" ? "ED25519" : "DKLS",
297
+ scheme: walletType === "SOLANA" || walletType === "STELLAR" ? "ED25519" : "DKLS",
296
298
  type: walletType,
297
299
  isPregen: true,
298
300
  pregenIdentifier,
@@ -158,7 +158,7 @@ class WalletService {
158
158
  return (0, import_wallet2.getSchemes)(types != null ? types : yield __privateGet(this, _getMissingTypes).call(this)).map((scheme) => {
159
159
  switch (scheme) {
160
160
  case "ED25519":
161
- return "SOLANA";
161
+ return supportedWalletTypes.some(({ type, optional }) => type === "STELLAR" && !optional) ? "STELLAR" : "SOLANA";
162
162
  default:
163
163
  return supportedWalletTypes.some(({ type, optional }) => type === "COSMOS" && !optional) ? "COSMOS" : "EVM";
164
164
  }
@@ -210,12 +210,14 @@ class WalletService {
210
210
  let wallet;
211
211
  let keygenRes;
212
212
  switch (walletType) {
213
+ case "STELLAR":
213
214
  case "SOLANA": {
214
215
  keygenRes = yield __privateGet(this, _paraCoreInterface).platformUtils.ed25519Keygen(
215
216
  __privateGet(this, _paraCoreInterface).ctx,
216
217
  __privateGet(this, _authService).userId,
217
218
  __privateGet(this, _paraCoreInterface).retrieveSessionCookie(),
218
- __privateGet(this, _paraCoreInterface).getBackupKitEmailProps()
219
+ __privateGet(this, _paraCoreInterface).getBackupKitEmailProps(),
220
+ walletType
219
221
  );
220
222
  break;
221
223
  }
@@ -232,7 +234,7 @@ class WalletService {
232
234
  }
233
235
  }
234
236
  const walletId = keygenRes.walletId;
235
- const walletScheme = walletType === "SOLANA" ? "ED25519" : "DKLS";
237
+ const walletScheme = walletType === "SOLANA" || walletType === "STELLAR" ? "ED25519" : "DKLS";
236
238
  signer = keygenRes.signer;
237
239
  yield __privateGet(this, _pollingService).poll({
238
240
  checkCondition: __privateGet(this, _pollingService).waitForWalletAddress({ walletId }),
@@ -366,6 +368,9 @@ class WalletService {
366
368
  prefix = (_b = (_a = options.cosmosPrefix) != null ? _a : __privateGet(this, _paraCoreInterface).cosmosPrefix) != null ? _b : "cosmos";
367
369
  str = (0, import_utils.getCosmosAddress)(wallet.publicKey, prefix);
368
370
  break;
371
+ case "STELLAR":
372
+ str = wallet.publicKey ? (0, import_utils.getStellarAddress)(wallet.publicKey) : (0, import_utils.getStellarAddressFromSolana)(wallet.address);
373
+ break;
369
374
  default:
370
375
  prefix = __privateGet(this, _paraCoreInterface).cosmosPrefix;
371
376
  str = wallet.address;
@@ -300,6 +300,47 @@ ${exportedAsBase64}
300
300
  }
301
301
  });
302
302
  }
303
+ /**
304
+ * Migrate a wallet share by encrypting it with the enclave's public key and
305
+ * sending the encrypted payload to the backend. The plaintext share never
306
+ * leaves the caller's process.
307
+ */
308
+ migrateShare(opts) {
309
+ return __async(this, null, function* () {
310
+ const { walletId, userShare, walletScheme, secretApiKey } = opts;
311
+ try {
312
+ const signer = this.extractSignerFromUserShare(userShare, walletId);
313
+ const shareData = {
314
+ // The enclave requires a non-empty userId but pregen wallets may not have one.
315
+ // We use walletId as a placeholder — the signing flow never reads this field.
316
+ userId: walletId,
317
+ walletId,
318
+ walletScheme,
319
+ signer
320
+ };
321
+ const encryptedPayload = yield this.encryptForEnclave(JSON.stringify({ shares: [shareData] }));
322
+ return this.userManagementClient.migrateWalletShare(walletId, JSON.stringify(encryptedPayload), secretApiKey);
323
+ } catch (error) {
324
+ throw new Error(
325
+ `Failed to migrate share for wallet ${walletId}: ${error instanceof Error ? error.message : "Unknown error"}`
326
+ );
327
+ }
328
+ });
329
+ }
330
+ extractSignerFromUserShare(userShare, walletId) {
331
+ const walletSegments = userShare.split("-");
332
+ for (const segment of walletSegments) {
333
+ try {
334
+ const decoded = JSON.parse(Buffer.from(segment, "base64").toString("utf-8"));
335
+ if (decoded.id === walletId && decoded.signer) {
336
+ return decoded.signer;
337
+ }
338
+ } catch (e) {
339
+ continue;
340
+ }
341
+ }
342
+ throw new Error(`No wallet with id ${walletId} found in the provided userShare`);
343
+ }
303
344
  persistSharesWithRetry(shares) {
304
345
  return __async(this, null, function* () {
305
346
  return yield this.persistShares(shares);
@@ -30,6 +30,8 @@ __export(formatting_exports, {
30
30
  compressPubkey: () => compressPubkey,
31
31
  decimalToHex: () => decimalToHex,
32
32
  getCosmosAddress: () => getCosmosAddress,
33
+ getStellarAddress: () => getStellarAddress,
34
+ getStellarAddressFromSolana: () => getStellarAddressFromSolana,
33
35
  hexStringToBase64: () => hexStringToBase64,
34
36
  hexToDecimal: () => hexToDecimal,
35
37
  hexToSignature: () => hexToSignature,
@@ -87,6 +89,96 @@ function rawSecp256k1PubkeyToRawAddress(pubkeyData) {
87
89
  }
88
90
  return (0, import_ripemd160.ripemd160)((0, import_sha256.sha256)(pubkeyData));
89
91
  }
92
+ const BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
93
+ const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
94
+ const BASE58_MAP = {};
95
+ for (let i = 0; i < BASE58_ALPHABET.length; i++) BASE58_MAP[BASE58_ALPHABET[i]] = i;
96
+ const STELLAR_ED25519_VERSION_BYTE = 6 << 3;
97
+ function crc16xmodem(data) {
98
+ let crc = 0;
99
+ for (const byte of data) {
100
+ crc ^= byte << 8;
101
+ for (let j = 0; j < 8; j++) {
102
+ crc = crc & 32768 ? crc << 1 ^ 4129 : crc << 1;
103
+ crc &= 65535;
104
+ }
105
+ }
106
+ return crc;
107
+ }
108
+ function base32Encode(data) {
109
+ let result = "";
110
+ let bits = 0;
111
+ let value = 0;
112
+ for (const byte of data) {
113
+ value = value << 8 | byte;
114
+ bits += 8;
115
+ while (bits >= 5) {
116
+ result += BASE32_ALPHABET[value >>> bits - 5 & 31];
117
+ bits -= 5;
118
+ }
119
+ }
120
+ if (bits > 0) {
121
+ result += BASE32_ALPHABET[value << 5 - bits & 31];
122
+ }
123
+ return result;
124
+ }
125
+ function base58Decode(str) {
126
+ const bytes = [0];
127
+ for (const char of str) {
128
+ let carry = BASE58_MAP[char];
129
+ if (carry === void 0) {
130
+ throw new Error(`Invalid base58 character: ${char}`);
131
+ }
132
+ for (let j = 0; j < bytes.length; j++) {
133
+ carry += bytes[j] * 58;
134
+ bytes[j] = carry & 255;
135
+ carry >>= 8;
136
+ }
137
+ while (carry > 0) {
138
+ bytes.push(carry & 255);
139
+ carry >>= 8;
140
+ }
141
+ }
142
+ let leadingZeros = 0;
143
+ for (const char of str) {
144
+ if (char !== "1") break;
145
+ leadingZeros++;
146
+ }
147
+ let sigBytes = bytes.length;
148
+ while (sigBytes > 0 && bytes[sigBytes - 1] === 0) sigBytes--;
149
+ const result = new Uint8Array(leadingZeros + sigBytes);
150
+ for (let i = 0; i < sigBytes; i++) {
151
+ result[leadingZeros + sigBytes - 1 - i] = bytes[i];
152
+ }
153
+ return result;
154
+ }
155
+ function encodeEd25519PublicKey(pubKeyBytes) {
156
+ if (pubKeyBytes.length !== 32) {
157
+ throw new Error(`Invalid Ed25519 public key length: expected 32 bytes, got ${pubKeyBytes.length}`);
158
+ }
159
+ const payload = new Uint8Array(1 + pubKeyBytes.length);
160
+ payload[0] = STELLAR_ED25519_VERSION_BYTE;
161
+ payload.set(pubKeyBytes, 1);
162
+ const checksum = crc16xmodem(payload);
163
+ const full = new Uint8Array(payload.length + 2);
164
+ full.set(payload);
165
+ full[payload.length] = checksum & 255;
166
+ full[payload.length + 1] = checksum >> 8 & 255;
167
+ return base32Encode(full);
168
+ }
169
+ function getStellarAddress(publicKey) {
170
+ if (!publicKey || publicKey.length === 0) {
171
+ return "";
172
+ }
173
+ const pubKeyBytes = Buffer.from(publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey, "hex");
174
+ return encodeEd25519PublicKey(pubKeyBytes);
175
+ }
176
+ function getStellarAddressFromSolana(solanaAddress) {
177
+ if (!solanaAddress || solanaAddress.length === 0) {
178
+ return "";
179
+ }
180
+ return encodeEd25519PublicKey(base58Decode(solanaAddress));
181
+ }
90
182
  function getCosmosAddress(publicKey, prefix) {
91
183
  if (!publicKey || publicKey.length === 0) {
92
184
  return "";
@@ -113,6 +205,8 @@ function truncateAddress(str, addressType, {
113
205
  compressPubkey,
114
206
  decimalToHex,
115
207
  getCosmosAddress,
208
+ getStellarAddress,
209
+ getStellarAddressFromSolana,
116
210
  hexStringToBase64,
117
211
  hexToDecimal,
118
212
  hexToSignature,
@@ -70,7 +70,8 @@ const WalletSchemeTypeMap = {
70
70
  COSMOS: true
71
71
  },
72
72
  ED25519: {
73
- SOLANA: true
73
+ SOLANA: true,
74
+ STELLAR: true
74
75
  }
75
76
  };
76
77
  function isPregenIdentifierMatch(a, b, type) {
@@ -2038,6 +2038,24 @@ const _ParaCore = class _ParaCore {
2038
2038
  return yield __privateGet(this, _walletService).setUserShare(base64Wallets);
2039
2039
  });
2040
2040
  }
2041
+ /**
2042
+ * Migrate a wallet share to the enclave. The share is ECIES-encrypted before
2043
+ * being sent so the plaintext never leaves the caller's process.
2044
+ */
2045
+ migrateWalletShare(opts) {
2046
+ return __async(this, null, function* () {
2047
+ if (!this.ctx.enclaveClient) {
2048
+ throw new Error("Enclave client not initialized");
2049
+ }
2050
+ const scheme = opts.walletScheme || "DKLS";
2051
+ return this.ctx.enclaveClient.migrateShare({
2052
+ walletId: opts.walletId,
2053
+ userShare: opts.userShare,
2054
+ walletScheme: scheme,
2055
+ secretApiKey: opts.secretApiKey
2056
+ });
2057
+ });
2058
+ }
2041
2059
  getTransactionReviewUrl(transactionId, timeoutMs) {
2042
2060
  return __async(this, null, function* () {
2043
2061
  const authMethods = yield this.supportedUserAuthMethods();
@@ -1,5 +1,5 @@
1
1
  import "./chunk-7B52C2XE.js";
2
- const PARA_CORE_VERSION = "2.19.0";
2
+ const PARA_CORE_VERSION = "2.20.0";
3
3
  const PREFIX = "@CAPSULE/";
4
4
  const PARA_PREFIX = "@PARA/";
5
5
  const LOCAL_STORAGE_AUTH_INFO = `${PREFIX}authInfo`;
@@ -220,12 +220,14 @@ class PregenWalletService {
220
220
  const [pregenIdentifierType, pregenIdentifier] = toPregenTypeAndId(pregenId);
221
221
  let keygenRes;
222
222
  switch (walletType) {
223
+ case "STELLAR":
223
224
  case "SOLANA":
224
225
  keygenRes = yield __privateGet(this, _paraCoreInterface).platformUtils.ed25519PreKeygen(
225
226
  __privateGet(this, _paraCoreInterface).ctx,
226
227
  pregenIdentifier,
227
228
  pregenIdentifierType,
228
- __privateGet(this, _paraCoreInterface).retrieveSessionCookie()
229
+ __privateGet(this, _paraCoreInterface).retrieveSessionCookie(),
230
+ walletType
229
231
  );
230
232
  break;
231
233
  default:
@@ -244,7 +246,7 @@ class PregenWalletService {
244
246
  __privateGet(this, _walletService).wallets[walletId] = {
245
247
  id: walletId,
246
248
  signer,
247
- scheme: walletType === "SOLANA" ? "ED25519" : "DKLS",
249
+ scheme: walletType === "SOLANA" || walletType === "STELLAR" ? "ED25519" : "DKLS",
248
250
  type: walletType,
249
251
  isPregen: true,
250
252
  pregenIdentifier,
@@ -17,7 +17,13 @@ import {
17
17
  migrateWallet,
18
18
  WalletSchemeTypeMap
19
19
  } from "../utils/wallet.js";
20
- import { dispatchEvent, getCosmosAddress, truncateAddress } from "../utils/index.js";
20
+ import {
21
+ dispatchEvent,
22
+ getCosmosAddress,
23
+ getStellarAddress,
24
+ getStellarAddressFromSolana,
25
+ truncateAddress
26
+ } from "../utils/index.js";
21
27
  import { ParaEvent } from "../types/events.js";
22
28
  import { LOCAL_STORAGE_CURRENT_WALLET_IDS, LOCAL_STORAGE_WALLETS, SHORT_POLLING_INTERVAL_MS } from "../constants.js";
23
29
  import { distributeNewShare } from "../shares/shareDistribution.js";
@@ -96,7 +102,7 @@ class WalletService {
96
102
  return getSchemes(types != null ? types : yield __privateGet(this, _getMissingTypes).call(this)).map((scheme) => {
97
103
  switch (scheme) {
98
104
  case "ED25519":
99
- return "SOLANA";
105
+ return supportedWalletTypes.some(({ type, optional }) => type === "STELLAR" && !optional) ? "STELLAR" : "SOLANA";
100
106
  default:
101
107
  return supportedWalletTypes.some(({ type, optional }) => type === "COSMOS" && !optional) ? "COSMOS" : "EVM";
102
108
  }
@@ -148,12 +154,14 @@ class WalletService {
148
154
  let wallet;
149
155
  let keygenRes;
150
156
  switch (walletType) {
157
+ case "STELLAR":
151
158
  case "SOLANA": {
152
159
  keygenRes = yield __privateGet(this, _paraCoreInterface).platformUtils.ed25519Keygen(
153
160
  __privateGet(this, _paraCoreInterface).ctx,
154
161
  __privateGet(this, _authService).userId,
155
162
  __privateGet(this, _paraCoreInterface).retrieveSessionCookie(),
156
- __privateGet(this, _paraCoreInterface).getBackupKitEmailProps()
163
+ __privateGet(this, _paraCoreInterface).getBackupKitEmailProps(),
164
+ walletType
157
165
  );
158
166
  break;
159
167
  }
@@ -170,7 +178,7 @@ class WalletService {
170
178
  }
171
179
  }
172
180
  const walletId = keygenRes.walletId;
173
- const walletScheme = walletType === "SOLANA" ? "ED25519" : "DKLS";
181
+ const walletScheme = walletType === "SOLANA" || walletType === "STELLAR" ? "ED25519" : "DKLS";
174
182
  signer = keygenRes.signer;
175
183
  yield __privateGet(this, _pollingService).poll({
176
184
  checkCondition: __privateGet(this, _pollingService).waitForWalletAddress({ walletId }),
@@ -304,6 +312,9 @@ class WalletService {
304
312
  prefix = (_b = (_a = options.cosmosPrefix) != null ? _a : __privateGet(this, _paraCoreInterface).cosmosPrefix) != null ? _b : "cosmos";
305
313
  str = getCosmosAddress(wallet.publicKey, prefix);
306
314
  break;
315
+ case "STELLAR":
316
+ str = wallet.publicKey ? getStellarAddress(wallet.publicKey) : getStellarAddressFromSolana(wallet.address);
317
+ break;
307
318
  default:
308
319
  prefix = __privateGet(this, _paraCoreInterface).cosmosPrefix;
309
320
  str = wallet.address;
@@ -261,6 +261,47 @@ ${exportedAsBase64}
261
261
  }
262
262
  });
263
263
  }
264
+ /**
265
+ * Migrate a wallet share by encrypting it with the enclave's public key and
266
+ * sending the encrypted payload to the backend. The plaintext share never
267
+ * leaves the caller's process.
268
+ */
269
+ migrateShare(opts) {
270
+ return __async(this, null, function* () {
271
+ const { walletId, userShare, walletScheme, secretApiKey } = opts;
272
+ try {
273
+ const signer = this.extractSignerFromUserShare(userShare, walletId);
274
+ const shareData = {
275
+ // The enclave requires a non-empty userId but pregen wallets may not have one.
276
+ // We use walletId as a placeholder — the signing flow never reads this field.
277
+ userId: walletId,
278
+ walletId,
279
+ walletScheme,
280
+ signer
281
+ };
282
+ const encryptedPayload = yield this.encryptForEnclave(JSON.stringify({ shares: [shareData] }));
283
+ return this.userManagementClient.migrateWalletShare(walletId, JSON.stringify(encryptedPayload), secretApiKey);
284
+ } catch (error) {
285
+ throw new Error(
286
+ `Failed to migrate share for wallet ${walletId}: ${error instanceof Error ? error.message : "Unknown error"}`
287
+ );
288
+ }
289
+ });
290
+ }
291
+ extractSignerFromUserShare(userShare, walletId) {
292
+ const walletSegments = userShare.split("-");
293
+ for (const segment of walletSegments) {
294
+ try {
295
+ const decoded = JSON.parse(Buffer.from(segment, "base64").toString("utf-8"));
296
+ if (decoded.id === walletId && decoded.signer) {
297
+ return decoded.signer;
298
+ }
299
+ } catch (e) {
300
+ continue;
301
+ }
302
+ }
303
+ throw new Error(`No wallet with id ${walletId} found in the provided userShare`);
304
+ }
264
305
  persistSharesWithRetry(shares) {
265
306
  return __async(this, null, function* () {
266
307
  return yield this.persistShares(shares);
@@ -48,6 +48,96 @@ function rawSecp256k1PubkeyToRawAddress(pubkeyData) {
48
48
  }
49
49
  return ripemd160(sha256(pubkeyData));
50
50
  }
51
+ const BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
52
+ const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
53
+ const BASE58_MAP = {};
54
+ for (let i = 0; i < BASE58_ALPHABET.length; i++) BASE58_MAP[BASE58_ALPHABET[i]] = i;
55
+ const STELLAR_ED25519_VERSION_BYTE = 6 << 3;
56
+ function crc16xmodem(data) {
57
+ let crc = 0;
58
+ for (const byte of data) {
59
+ crc ^= byte << 8;
60
+ for (let j = 0; j < 8; j++) {
61
+ crc = crc & 32768 ? crc << 1 ^ 4129 : crc << 1;
62
+ crc &= 65535;
63
+ }
64
+ }
65
+ return crc;
66
+ }
67
+ function base32Encode(data) {
68
+ let result = "";
69
+ let bits = 0;
70
+ let value = 0;
71
+ for (const byte of data) {
72
+ value = value << 8 | byte;
73
+ bits += 8;
74
+ while (bits >= 5) {
75
+ result += BASE32_ALPHABET[value >>> bits - 5 & 31];
76
+ bits -= 5;
77
+ }
78
+ }
79
+ if (bits > 0) {
80
+ result += BASE32_ALPHABET[value << 5 - bits & 31];
81
+ }
82
+ return result;
83
+ }
84
+ function base58Decode(str) {
85
+ const bytes = [0];
86
+ for (const char of str) {
87
+ let carry = BASE58_MAP[char];
88
+ if (carry === void 0) {
89
+ throw new Error(`Invalid base58 character: ${char}`);
90
+ }
91
+ for (let j = 0; j < bytes.length; j++) {
92
+ carry += bytes[j] * 58;
93
+ bytes[j] = carry & 255;
94
+ carry >>= 8;
95
+ }
96
+ while (carry > 0) {
97
+ bytes.push(carry & 255);
98
+ carry >>= 8;
99
+ }
100
+ }
101
+ let leadingZeros = 0;
102
+ for (const char of str) {
103
+ if (char !== "1") break;
104
+ leadingZeros++;
105
+ }
106
+ let sigBytes = bytes.length;
107
+ while (sigBytes > 0 && bytes[sigBytes - 1] === 0) sigBytes--;
108
+ const result = new Uint8Array(leadingZeros + sigBytes);
109
+ for (let i = 0; i < sigBytes; i++) {
110
+ result[leadingZeros + sigBytes - 1 - i] = bytes[i];
111
+ }
112
+ return result;
113
+ }
114
+ function encodeEd25519PublicKey(pubKeyBytes) {
115
+ if (pubKeyBytes.length !== 32) {
116
+ throw new Error(`Invalid Ed25519 public key length: expected 32 bytes, got ${pubKeyBytes.length}`);
117
+ }
118
+ const payload = new Uint8Array(1 + pubKeyBytes.length);
119
+ payload[0] = STELLAR_ED25519_VERSION_BYTE;
120
+ payload.set(pubKeyBytes, 1);
121
+ const checksum = crc16xmodem(payload);
122
+ const full = new Uint8Array(payload.length + 2);
123
+ full.set(payload);
124
+ full[payload.length] = checksum & 255;
125
+ full[payload.length + 1] = checksum >> 8 & 255;
126
+ return base32Encode(full);
127
+ }
128
+ function getStellarAddress(publicKey) {
129
+ if (!publicKey || publicKey.length === 0) {
130
+ return "";
131
+ }
132
+ const pubKeyBytes = Buffer.from(publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey, "hex");
133
+ return encodeEd25519PublicKey(pubKeyBytes);
134
+ }
135
+ function getStellarAddressFromSolana(solanaAddress) {
136
+ if (!solanaAddress || solanaAddress.length === 0) {
137
+ return "";
138
+ }
139
+ return encodeEd25519PublicKey(base58Decode(solanaAddress));
140
+ }
51
141
  function getCosmosAddress(publicKey, prefix) {
52
142
  if (!publicKey || publicKey.length === 0) {
53
143
  return "";
@@ -73,6 +163,8 @@ export {
73
163
  compressPubkey,
74
164
  decimalToHex,
75
165
  getCosmosAddress,
166
+ getStellarAddress,
167
+ getStellarAddressFromSolana,
76
168
  hexStringToBase64,
77
169
  hexToDecimal,
78
170
  hexToSignature,
@@ -14,7 +14,8 @@ const WalletSchemeTypeMap = {
14
14
  COSMOS: true
15
15
  },
16
16
  ED25519: {
17
- SOLANA: true
17
+ SOLANA: true,
18
+ STELLAR: true
18
19
  }
19
20
  };
20
21
  function isPregenIdentifierMatch(a, b, type) {
@@ -1,4 +1,4 @@
1
- import { AuthMethod, AuthExtras, CurrentWalletIds, EmailTheme, PartnerEntity, TWalletType, PregenIds, BiometricLocationHint, Auth, SupportedWalletTypes, AuthIdentifier, AuthType, ExternalWalletInfo, PrimaryAuthInfo, SessionInfo, PrimaryAuth, PrimaryAuthType, AccountMetadata, LinkedAccounts, VerifyLinkParams, VerifyExternalWalletParams as VerifyExternalWalletParamsServer, SupportedAccountLinks, OnRampPurchase, BalancesConfig, Theme, IssueJwtParams } from '@getpara/user-management-client';
1
+ import { AuthMethod, AuthExtras, CurrentWalletIds, EmailTheme, PartnerEntity, TWalletType, PregenIds, BiometricLocationHint, Auth, SupportedWalletTypes, AuthIdentifier, AuthType, ExternalWalletInfo, PrimaryAuthInfo, SessionInfo, PrimaryAuth, PrimaryAuthType, AccountMetadata, LinkedAccounts, VerifyLinkParams, VerifyExternalWalletParams as VerifyExternalWalletParamsServer, SupportedAccountLinks, OnRampPurchase, BalancesConfig, Theme, IssueJwtParams, TWalletScheme } from '@getpara/user-management-client';
2
2
  import type { pki as pkiType } from 'node-forge';
3
3
  import { Ctx, Environment, Wallet, ConstructorOpts, CoreAuthInfo, CoreMethodParams, CoreMethodResponse, CoreInterface, AccountLinkInProgress, InternalMethodParams, InternalMethodResponse, OAuthResponse, AvailableWallet } from './types/index.js';
4
4
  import { PlatformUtils } from './PlatformUtils.js';
@@ -721,6 +721,16 @@ export declare abstract class ParaCore implements CoreInterface {
721
721
  * @param {string} base64Wallet the encoded wallet string
722
722
  **/
723
723
  setUserShare(base64Wallets: string): Promise<void>;
724
+ /**
725
+ * Migrate a wallet share to the enclave. The share is ECIES-encrypted before
726
+ * being sent so the plaintext never leaves the caller's process.
727
+ */
728
+ migrateWalletShare(opts: {
729
+ walletId: string;
730
+ userShare: string;
731
+ secretApiKey: string;
732
+ walletScheme?: TWalletScheme;
733
+ }): Promise<any>;
724
734
  private getTransactionReviewUrl;
725
735
  private getOnRampTransactionUrl;
726
736
  getWalletBalance(params: GetWalletBalanceParams): Promise<string>;
@@ -32,12 +32,12 @@ export interface PlatformUtils {
32
32
  r: Buffer;
33
33
  s: Buffer;
34
34
  }>;
35
- ed25519Keygen(ctx: Ctx, userId: string, sessionCookie: string, emailProps?: BackupKitEmailProps): Promise<{
35
+ ed25519Keygen(ctx: Ctx, userId: string, sessionCookie: string, emailProps?: BackupKitEmailProps, type?: TWalletType): Promise<{
36
36
  signer: string;
37
37
  walletId: string;
38
38
  }>;
39
39
  ed25519Sign(ctx: Ctx, userId: string, walletId: string, share: string, base64Bytes: string, sessionCookie: string): Promise<SignatureRes>;
40
- ed25519PreKeygen(ctx: Ctx, pregenIdentifier: string, pregenIdentifierType: TPregenIdentifierType, sessionCookie: string): Promise<{
40
+ ed25519PreKeygen(ctx: Ctx, pregenIdentifier: string, pregenIdentifierType: TPregenIdentifierType, sessionCookie: string, type?: TWalletType): Promise<{
41
41
  signer: string;
42
42
  walletId: string;
43
43
  }>;
@@ -88,6 +88,18 @@ export declare class EnclaveClient {
88
88
  walletIds: string[];
89
89
  partnerId: string;
90
90
  }): Promise<ShareData[]>;
91
+ /**
92
+ * Migrate a wallet share by encrypting it with the enclave's public key and
93
+ * sending the encrypted payload to the backend. The plaintext share never
94
+ * leaves the caller's process.
95
+ */
96
+ migrateShare(opts: {
97
+ walletId: string;
98
+ userShare: string;
99
+ walletScheme: string;
100
+ secretApiKey: string;
101
+ }): Promise<any>;
102
+ private extractSignerFromUserShare;
91
103
  persistSharesWithRetry(shares: ShareData[]): Promise<any>;
92
104
  deleteSharesWithRetry(): Promise<void>;
93
105
  }
@@ -12,6 +12,8 @@ export declare function hexToDecimal(hex: string): string;
12
12
  export declare function decimalToHex(decimal: string): Hex;
13
13
  export declare function compressPubkey(pubkey: Uint8Array): Uint8Array;
14
14
  export declare function rawSecp256k1PubkeyToRawAddress(pubkeyData: Uint8Array): Uint8Array;
15
+ export declare function getStellarAddress(publicKey: string): string;
16
+ export declare function getStellarAddressFromSolana(solanaAddress: string): string;
15
17
  export declare function getCosmosAddress(publicKey: string, prefix: string): string;
16
18
  export declare function truncateAddress(str: string, addressType: TWalletType, { prefix, targetLength, }?: {
17
19
  prefix?: string;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@getpara/core-sdk",
3
- "version": "2.19.0",
3
+ "version": "2.20.0",
4
4
  "dependencies": {
5
5
  "@celo/utils": "^8.0.2",
6
6
  "@cosmjs/encoding": "^0.32.4",
7
7
  "@ethereumjs/util": "^9.1.0",
8
- "@getpara/user-management-client": "2.19.0",
8
+ "@getpara/user-management-client": "2.20.0",
9
9
  "@noble/hashes": "^1.5.0",
10
10
  "axios": "^1.8.4",
11
11
  "base64url": "^3.0.1",
@@ -30,7 +30,7 @@
30
30
  "dist",
31
31
  "package.json"
32
32
  ],
33
- "gitHead": "7dc9400777adb653c0cc28e0d9236424eb384467",
33
+ "gitHead": "a8443bcc4018864f5e582f238ade1bb3b4e121f4",
34
34
  "main": "dist/cjs/index.js",
35
35
  "module": "dist/esm/index.js",
36
36
  "scripts": {