@textrp/briij-js-sdk 42.0.0 → 43.1.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +7 -4
  2. package/README.md +71 -0
  3. package/lib/@types/auth.d.ts +57 -2
  4. package/lib/@types/auth.d.ts.map +1 -1
  5. package/lib/@types/auth.js +2 -0
  6. package/lib/@types/auth.js.map +1 -1
  7. package/lib/@types/event.d.ts +3 -0
  8. package/lib/@types/event.d.ts.map +1 -1
  9. package/lib/@types/event.js.map +1 -1
  10. package/lib/@types/synapse.d.ts +64 -0
  11. package/lib/@types/synapse.d.ts.map +1 -1
  12. package/lib/@types/synapse.js.map +1 -1
  13. package/lib/briij.d.ts +2 -0
  14. package/lib/briij.d.ts.map +1 -1
  15. package/lib/briij.js +2 -0
  16. package/lib/briij.js.map +1 -1
  17. package/lib/client.d.ts +100 -7
  18. package/lib/client.d.ts.map +1 -1
  19. package/lib/client.js +469 -213
  20. package/lib/client.js.map +1 -1
  21. package/lib/wallet-recovery.d.ts +24 -0
  22. package/lib/wallet-recovery.d.ts.map +1 -0
  23. package/lib/wallet-recovery.js +256 -0
  24. package/lib/wallet-recovery.js.map +1 -0
  25. package/lib/xrpl/identity.d.ts +2 -1
  26. package/lib/xrpl/identity.d.ts.map +1 -1
  27. package/lib/xrpl/identity.js +70 -47
  28. package/lib/xrpl/identity.js.map +1 -1
  29. package/lib/xrpl/trust.d.ts +4 -2
  30. package/lib/xrpl/trust.d.ts.map +1 -1
  31. package/lib/xrpl/trust.js +31 -19
  32. package/lib/xrpl/trust.js.map +1 -1
  33. package/lib/xrpl/verification.js +17 -6
  34. package/lib/xrpl/verification.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/@types/auth.ts +61 -2
  37. package/src/@types/event.ts +3 -0
  38. package/src/@types/synapse.ts +77 -0
  39. package/src/briij.ts +2 -0
  40. package/src/client.ts +344 -46
  41. package/src/wallet-recovery.ts +327 -0
  42. package/src/xrpl/identity.ts +66 -39
  43. package/src/xrpl/trust.ts +35 -18
  44. package/src/xrpl/verification.ts +19 -6
package/src/client.ts CHANGED
@@ -170,7 +170,19 @@ import {
170
170
  type IStateEventWithRoomId,
171
171
  SearchOrderBy,
172
172
  } from "./@types/search.ts";
173
- import { type ISynapseAdminDeactivateResponse, type ISynapseAdminWhoisResponse } from "./@types/synapse.ts";
173
+ import {
174
+ type IBriijAdminCreatePremiumFeatureRequest,
175
+ type IBriijAdminPremiumFeaturesResponse,
176
+ type IBriijAdminUpdatePremiumFeatureRequest,
177
+ type IBriijLegacyEnabledFeaturesResponse,
178
+ type IBriijLegacyMyAddressResponse,
179
+ type IBriijMcreditsBalanceResponse,
180
+ type IBriijMcreditsFeaturesResponse,
181
+ type IBriijMcreditsSpendResponse,
182
+ type IBriijPremiumFeature,
183
+ type ISynapseAdminDeactivateResponse,
184
+ type ISynapseAdminWhoisResponse,
185
+ } from "./@types/synapse.ts";
174
186
  import { type IHierarchyRoom } from "./@types/spaces.ts";
175
187
  import {
176
188
  type IPusher,
@@ -198,7 +210,14 @@ import {
198
210
  type LoginResponse,
199
211
  type LoginTokenPostResponse,
200
212
  type SSOAction,
213
+ WALLET_E2EE_RECOVERY_ACCOUNT_DATA_TYPE,
214
+ WALLET_IDENTITY_ACCOUNT_DATA_TYPE,
201
215
  XRPL_WALLET_LOGIN_TYPE,
216
+ type WalletE2eeRecoveryEnvelope,
217
+ type WalletIdentityAccountData,
218
+ type XrplAuthChallengeRequest,
219
+ type XrplAuthChallengeResponse,
220
+ type XrplAuthCompleteRequest,
202
221
  type XrplWalletChallengePayload,
203
222
  } from "./@types/auth.ts";
204
223
  import { TypedEventEmitter } from "./models/typed-event-emitter.ts";
@@ -248,13 +267,14 @@ import {
248
267
  type OidcClientConfig,
249
268
  validateAuthMetadataAndKeys,
250
269
  } from "./oidc/index.ts";
251
- import { configureXrplIdentityMinting, mintSoulboundIdentityNFT } from "./xrpl/identity.ts";
252
270
  import {
253
- XRPL_VERIFIED_EVENT,
254
- XRPL_VERIFY_ACCEPT_EVENT,
255
- XRPL_VERIFY_REQUEST_EVENT,
256
- } from "./xrpl/verification.ts";
257
- import { configureXrplTrust } from "./xrpl/trust.ts";
271
+ getConfiguredXrplIdentityMintingConfig,
272
+ mintSoulboundIdentityNFT,
273
+ type XamanWalletAdapter,
274
+ type XrplIdentityMintingConfig,
275
+ } from "./xrpl/identity.ts";
276
+ import { XRPL_VERIFIED_EVENT, XRPL_VERIFY_ACCEPT_EVENT, XRPL_VERIFY_REQUEST_EVENT } from "./xrpl/verification.ts";
277
+ import { type XrplTrustConfig } from "./xrpl/trust.ts";
258
278
  import { type EmptyObject } from "./@types/common.ts";
259
279
  import { UnsupportedDelayedEventsEndpointError, UnsupportedStickyEventsEndpointError } from "./errors.ts";
260
280
  import { type Transport } from "./matrixrtc/index.ts";
@@ -471,6 +491,17 @@ export interface ICreateClientOpts {
471
491
  * Defaults to the built-in global logger; see {@link DebugLogger} for an alternative.
472
492
  */
473
493
  logger?: Logger;
494
+
495
+ /**
496
+ * Optional per-client XRPL trust configuration.
497
+ */
498
+ xrplTrust?: Partial<XrplTrustConfig>;
499
+
500
+ /**
501
+ * Optional per-client XRPL identity minting configuration.
502
+ */
503
+ xrplIdentityMinting?: Partial<Omit<XrplIdentityMintingConfig, "homeserverBaseUrl" | "accessToken">>;
504
+ xamanWallet?: XamanWalletAdapter;
474
505
  }
475
506
 
476
507
  export interface IBriijClientCreateOpts extends ICreateClientOpts {
@@ -1291,6 +1322,9 @@ export class BriijClient extends TypedEventEmitter<EmittedEvents, ClientEventHan
1291
1322
  protected clientOpts?: IStoredClientOpts;
1292
1323
  protected clientWellKnownIntervalID?: ReturnType<typeof setInterval>;
1293
1324
  protected canResetTimelineCallback?: ResetTimelineCallback;
1325
+ private xrplTrustConfig?: XrplTrustConfig;
1326
+ private xrplIdentityMintingConfig: Partial<Omit<XrplIdentityMintingConfig, "homeserverBaseUrl" | "accessToken">> =
1327
+ {};
1294
1328
 
1295
1329
  public canSupport = new Map<Feature, ServerSupport>();
1296
1330
 
@@ -1351,6 +1385,17 @@ export class BriijClient extends TypedEventEmitter<EmittedEvents, ClientEventHan
1351
1385
 
1352
1386
  const userId = opts.userId || null;
1353
1387
  this.credentials = { userId };
1388
+ if (opts.xrplTrust) {
1389
+ this.xrplTrustConfig = {
1390
+ homeserverBaseUrl: opts.xrplTrust.homeserverBaseUrl ?? this.baseUrl,
1391
+ accessToken: opts.xrplTrust.accessToken ?? opts.accessToken ?? "",
1392
+ trustPath: opts.xrplTrust.trustPath,
1393
+ };
1394
+ }
1395
+ this.xrplIdentityMintingConfig = {
1396
+ ...(opts.xrplIdentityMinting ?? {}),
1397
+ ...(opts.xamanWallet ? { xamanWallet: opts.xamanWallet } : {}),
1398
+ };
1354
1399
 
1355
1400
  this.http = new BriijHttpApi(this as ConstructorParameters<typeof BriijHttpApi>[0], {
1356
1401
  fetchFn: opts.fetchFn,
@@ -6056,6 +6101,41 @@ export class BriijClient extends TypedEventEmitter<EmittedEvents, ClientEventHan
6056
6101
  return this.fallbackICEServerAllowed;
6057
6102
  }
6058
6103
 
6104
+ /**
6105
+ * Some briij deployments mount admin resources under `/_briij/admin` while
6106
+ * Synapse defaults to `/_synapse/admin`. Try both prefixes to stay compatible.
6107
+ */
6108
+ private async authedRequestWithAdminPrefixes<T>(
6109
+ method: Method,
6110
+ adminSubPath: string,
6111
+ queryParams?: QueryDict,
6112
+ body?: Body,
6113
+ ): Promise<T> {
6114
+ const normalizedSubPath = adminSubPath.replace(/^\/+/, "");
6115
+ const adminPrefixes = ["/_synapse/admin", "/_briij/admin"];
6116
+ let lastError: unknown;
6117
+
6118
+ for (const adminPrefix of adminPrefixes) {
6119
+ try {
6120
+ return await this.http.authedRequest<T>(
6121
+ method,
6122
+ `${adminPrefix}/${normalizedSubPath}`,
6123
+ queryParams,
6124
+ body,
6125
+ { prefix: "" },
6126
+ );
6127
+ } catch (error) {
6128
+ if (error instanceof BriijError && error.httpStatus === 404) {
6129
+ lastError = error;
6130
+ continue;
6131
+ }
6132
+ throw error;
6133
+ }
6134
+ }
6135
+
6136
+ throw lastError ?? new Error("Admin API endpoint not found");
6137
+ }
6138
+
6059
6139
  /**
6060
6140
  * Determines if the current user is an administrator of the Synapse homeserver.
6061
6141
  * Returns false if untrue or the homeserver does not appear to be a Synapse
@@ -6063,11 +6143,20 @@ export class BriijClient extends TypedEventEmitter<EmittedEvents, ClientEventHan
6063
6143
  * as a result.</strong>
6064
6144
  * @returns true if the user appears to be a Synapse administrator.
6065
6145
  */
6066
- public isSynapseAdministrator(): Promise<boolean> {
6067
- const path = utils.encodeUri("/_synapse/admin/v1/users/$userId/admin", { $userId: this.getUserId()! });
6068
- return this.http
6069
- .authedRequest<{ admin: boolean }>(Method.Get, path, undefined, undefined, { prefix: "" })
6070
- .then((r) => r.admin); // pull out the specific boolean we want
6146
+ public async isSynapseAdministrator(): Promise<boolean> {
6147
+ const adminSubPath = utils.encodeUri("v1/users/$userId/admin", { $userId: this.getUserId()! });
6148
+ try {
6149
+ const response = await this.authedRequestWithAdminPrefixes<{ admin: boolean }>(Method.Get, adminSubPath);
6150
+ return response.admin;
6151
+ } catch (error) {
6152
+ if (error instanceof BriijError && error.httpStatus === 404) {
6153
+ return false;
6154
+ }
6155
+ if (error instanceof Error && /Admin API endpoint not found/i.test(error.message)) {
6156
+ return false;
6157
+ }
6158
+ throw error;
6159
+ }
6071
6160
  }
6072
6161
 
6073
6162
  /**
@@ -6078,8 +6167,8 @@ export class BriijClient extends TypedEventEmitter<EmittedEvents, ClientEventHan
6078
6167
  * @returns the whois response - see Synapse docs for information.
6079
6168
  */
6080
6169
  public whoisSynapseUser(userId: string): Promise<ISynapseAdminWhoisResponse> {
6081
- const path = utils.encodeUri("/_synapse/admin/v1/whois/$userId", { $userId: userId });
6082
- return this.http.authedRequest(Method.Get, path, undefined, undefined, { prefix: "" });
6170
+ const adminSubPath = utils.encodeUri("v1/whois/$userId", { $userId: userId });
6171
+ return this.authedRequestWithAdminPrefixes(Method.Get, adminSubPath);
6083
6172
  }
6084
6173
 
6085
6174
  /**
@@ -6089,8 +6178,117 @@ export class BriijClient extends TypedEventEmitter<EmittedEvents, ClientEventHan
6089
6178
  * @returns the deactivate response - see Synapse docs for information.
6090
6179
  */
6091
6180
  public deactivateSynapseUser(userId: string): Promise<ISynapseAdminDeactivateResponse> {
6092
- const path = utils.encodeUri("/_synapse/admin/v1/deactivate/$userId", { $userId: userId });
6093
- return this.http.authedRequest(Method.Post, path, undefined, undefined, { prefix: "" });
6181
+ const adminSubPath = utils.encodeUri("v1/deactivate/$userId", { $userId: userId });
6182
+ return this.authedRequestWithAdminPrefixes(Method.Post, adminSubPath);
6183
+ }
6184
+
6185
+ /**
6186
+ * Lists active mCredits features for the authenticated user.
6187
+ */
6188
+ public getBriijMcreditsFeatures(): Promise<IBriijMcreditsFeaturesResponse> {
6189
+ return this.http.authedRequest(Method.Get, "/mcredits/features", undefined, undefined, {
6190
+ prefix: ClientPrefix.V3,
6191
+ });
6192
+ }
6193
+
6194
+ /**
6195
+ * Retrieves the authenticated user's mCredits balance.
6196
+ */
6197
+ public getBriijMcreditsBalance(): Promise<IBriijMcreditsBalanceResponse> {
6198
+ return this.http.authedRequest(Method.Get, "/mcredits/balance", undefined, undefined, {
6199
+ prefix: ClientPrefix.V3,
6200
+ });
6201
+ }
6202
+
6203
+ /**
6204
+ * Spends mCredits for a premium feature.
6205
+ * @param featureKey - The premium feature identifier to spend against.
6206
+ */
6207
+ public spendBriijMcredits(featureKey: string): Promise<IBriijMcreditsSpendResponse> {
6208
+ return this.http.authedRequest(
6209
+ Method.Post,
6210
+ "/mcredits/spend",
6211
+ undefined,
6212
+ { feature_key: featureKey },
6213
+ {
6214
+ prefix: ClientPrefix.V3,
6215
+ },
6216
+ );
6217
+ }
6218
+
6219
+ /**
6220
+ * Calls Briij's legacy-compatible endpoint to resolve a Matrix user to wallet/mcredit payload.
6221
+ * @param matrixUserId - Matrix user ID used by legacy clients.
6222
+ */
6223
+ public getBriijLegacyMyAddress(matrixUserId: string): Promise<IBriijLegacyMyAddressResponse> {
6224
+ return this.http.authedRequest(
6225
+ Method.Post,
6226
+ "/my-address",
6227
+ undefined,
6228
+ { address: matrixUserId },
6229
+ { prefix: "" },
6230
+ );
6231
+ }
6232
+
6233
+ /**
6234
+ * Calls Briij's legacy-compatible enabled-features endpoint.
6235
+ * @param walletAddress - XRPL wallet address.
6236
+ * @param network - Legacy network segment; defaults to `main`.
6237
+ */
6238
+ public getBriijLegacyEnabledFeatures(
6239
+ walletAddress: string,
6240
+ network = "main",
6241
+ ): Promise<IBriijLegacyEnabledFeaturesResponse> {
6242
+ const path = utils.encodeUri("/my-features/$walletAddress/$network/enabled", {
6243
+ $walletAddress: walletAddress,
6244
+ $network: network,
6245
+ });
6246
+ return this.http.authedRequest(Method.Get, path, undefined, undefined, { prefix: "" });
6247
+ }
6248
+
6249
+ /**
6250
+ * Lists mCredits premium features from Synapse admin APIs.
6251
+ */
6252
+ public async getBriijAdminPremiumFeatures(): Promise<IBriijPremiumFeature[]> {
6253
+ const response = await this.authedRequestWithAdminPrefixes<IBriijAdminPremiumFeaturesResponse>(
6254
+ Method.Get,
6255
+ "v2/briij/premium_features",
6256
+ );
6257
+ return response.premium_features;
6258
+ }
6259
+
6260
+ /**
6261
+ * Creates an mCredits premium feature via Synapse admin APIs.
6262
+ * @param body - Feature fields to create.
6263
+ */
6264
+ public createBriijAdminPremiumFeature(body: IBriijAdminCreatePremiumFeatureRequest): Promise<IBriijPremiumFeature> {
6265
+ return this.authedRequestWithAdminPrefixes(Method.Post, "v2/briij/premium_features", undefined, body);
6266
+ }
6267
+
6268
+ /**
6269
+ * Updates an mCredits premium feature via Synapse admin APIs.
6270
+ * @param featureKey - The premium feature key to update.
6271
+ * @param body - Updatable feature fields.
6272
+ */
6273
+ public updateBriijAdminPremiumFeature(
6274
+ featureKey: string,
6275
+ body: IBriijAdminUpdatePremiumFeatureRequest,
6276
+ ): Promise<IBriijPremiumFeature> {
6277
+ const adminSubPath = utils.encodeUri("v2/briij/premium_features/$featureKey", {
6278
+ $featureKey: featureKey,
6279
+ });
6280
+ return this.authedRequestWithAdminPrefixes(Method.Put, adminSubPath, undefined, body);
6281
+ }
6282
+
6283
+ /**
6284
+ * Soft-deactivates an mCredits premium feature via Synapse admin APIs.
6285
+ * @param featureKey - The premium feature key to deactivate.
6286
+ */
6287
+ public deactivateBriijAdminPremiumFeature(featureKey: string): Promise<IBriijPremiumFeature> {
6288
+ const adminSubPath = utils.encodeUri("v2/briij/premium_features/$featureKey", {
6289
+ $featureKey: featureKey,
6290
+ });
6291
+ return this.authedRequestWithAdminPrefixes(Method.Delete, adminSubPath);
6094
6292
  }
6095
6293
 
6096
6294
  protected async fetchClientWellKnown(): Promise<void> {
@@ -6680,32 +6878,44 @@ export class BriijClient extends TypedEventEmitter<EmittedEvents, ClientEventHan
6680
6878
  type: loginType,
6681
6879
  });
6682
6880
 
6683
- if (response.access_token && response.user_id) {
6684
- this.http.opts.accessToken = response.access_token;
6685
- this.credentials = {
6686
- userId: response.user_id,
6687
- };
6688
- configureXrplTrust({
6689
- homeserverBaseUrl: this.baseUrl,
6690
- accessToken: response.access_token,
6691
- });
6881
+ await this.applyLoginResponse(response, loginType);
6882
+
6883
+ return response;
6884
+ }
6885
+
6886
+ private async applyLoginResponse(response: LoginResponse, loginType?: LoginRequest["type"]): Promise<void> {
6887
+ if (!response.access_token || !response.user_id) {
6888
+ return;
6692
6889
  }
6693
6890
 
6891
+ this.http.opts.accessToken = response.access_token;
6892
+ this.credentials = {
6893
+ userId: response.user_id,
6894
+ };
6895
+ this.deviceId = response.device_id ?? this.deviceId;
6896
+ this.xrplTrustConfig = {
6897
+ homeserverBaseUrl: this.baseUrl,
6898
+ accessToken: response.access_token,
6899
+ trustPath: this.xrplTrustConfig?.trustPath,
6900
+ };
6901
+
6694
6902
  // After Xaman-backed SSO login, mint once and persist identity metadata in account_data.
6695
- if (loginType === "m.login.token" && response.access_token && response.user_id) {
6696
- configureXrplIdentityMinting({
6697
- homeserverBaseUrl: this.baseUrl,
6698
- accessToken: response.access_token,
6699
- });
6903
+ if (loginType === "m.login.token") {
6904
+ const fallbackMintingConfig = getConfiguredXrplIdentityMintingConfig();
6905
+ const xamanWallet = this.xrplIdentityMintingConfig.xamanWallet ?? fallbackMintingConfig.xamanWallet;
6700
6906
 
6701
6907
  try {
6702
- await mintSoulboundIdentityNFT(response.user_id);
6908
+ await mintSoulboundIdentityNFT(response.user_id, {
6909
+ ...fallbackMintingConfig,
6910
+ ...this.xrplIdentityMintingConfig,
6911
+ homeserverBaseUrl: this.baseUrl,
6912
+ accessToken: response.access_token,
6913
+ xamanWallet,
6914
+ });
6703
6915
  } catch (error) {
6704
6916
  logger.warn("XRPL identity NFT minting skipped/failed", error);
6705
6917
  }
6706
6918
  }
6707
-
6708
- return response;
6709
6919
  }
6710
6920
 
6711
6921
  /**
@@ -6724,32 +6934,120 @@ export class BriijClient extends TypedEventEmitter<EmittedEvents, ClientEventHan
6724
6934
  }
6725
6935
 
6726
6936
  /**
6727
- * @param user - Matrix user ID localpart or fully qualified MXID.
6728
- * @param walletAddress - XRPL/Xahau classic wallet address.
6729
- * @param signature - Hex signature for the challenge message.
6730
- * @param challenge - Signed challenge payload.
6731
- * @param network - Ledger network identifier. Defaults to `xrpl`.
6937
+ * Request an XRPL login challenge from the homeserver.
6938
+ *
6939
+ * The briij homeserver responds with HTTP 401 as the successful challenge
6940
+ * response, so this helper normalizes that into a resolved promise.
6941
+ */
6942
+ public async getXrplAuthChallenge(
6943
+ request: Omit<XrplAuthChallengeRequest, "type">,
6944
+ ): Promise<XrplAuthChallengeResponse> {
6945
+ try {
6946
+ const response = (await this.loginRequest({
6947
+ ...request,
6948
+ type: XRPL_WALLET_LOGIN_TYPE,
6949
+ })) as unknown as XrplAuthChallengeResponse;
6950
+ if (typeof response.session === "string" && typeof response.challenge === "string") {
6951
+ return response;
6952
+ }
6953
+ } catch (error) {
6954
+ if (error instanceof BriijError && error.httpStatus === 401) {
6955
+ const session = error.data?.session;
6956
+ const challenge = error.data?.challenge;
6957
+ if (typeof session === "string" && typeof challenge === "string") {
6958
+ return { session, challenge };
6959
+ }
6960
+ }
6961
+ throw error;
6962
+ }
6963
+
6964
+ throw new Error("XRPL challenge response was not returned by homeserver");
6965
+ }
6966
+
6967
+ /**
6968
+ * Complete XRPL login using the previously issued challenge session.
6969
+ *
6732
6970
  * @returns Promise which resolves to a LoginResponse object.
6733
6971
  * @returns Rejects: with an error response.
6734
6972
  */
6735
- public loginWithXrplWallet(
6973
+ public completeXrplAuth(request: Omit<XrplAuthCompleteRequest, "type">): Promise<LoginResponse> {
6974
+ return this.loginRequest({
6975
+ ...request,
6976
+ type: XRPL_WALLET_LOGIN_TYPE,
6977
+ });
6978
+ }
6979
+
6980
+ /**
6981
+ * Store a chain-agnostic wallet recovery envelope in account data.
6982
+ *
6983
+ * This uses a stable account-data type and does not affect core E2EE state.
6984
+ *
6985
+ * @param envelope - Wallet recovery envelope payload.
6986
+ */
6987
+ public async setWalletRecoveryEnvelope(envelope: WalletE2eeRecoveryEnvelope): Promise<EmptyObject> {
6988
+ return await this.setAccountData(WALLET_E2EE_RECOVERY_ACCOUNT_DATA_TYPE, envelope);
6989
+ }
6990
+
6991
+ /**
6992
+ * Fetch wallet recovery envelope directly from the homeserver.
6993
+ *
6994
+ * @returns The stored envelope, or null if not found.
6995
+ */
6996
+ public getWalletRecoveryEnvelopeFromServer(): Promise<WalletE2eeRecoveryEnvelope | null> {
6997
+ return this.getAccountDataFromServer(WALLET_E2EE_RECOVERY_ACCOUNT_DATA_TYPE);
6998
+ }
6999
+
7000
+ /**
7001
+ * Fetch canonical wallet identity metadata from the homeserver.
7002
+ *
7003
+ * @returns Wallet identity metadata, or null if not found.
7004
+ */
7005
+ public getWalletIdentityFromServer(): Promise<WalletIdentityAccountData | null> {
7006
+ return this.getAccountDataFromServer(WALLET_IDENTITY_ACCOUNT_DATA_TYPE);
7007
+ }
7008
+
7009
+ /**
7010
+ * @deprecated Use `getXrplAuthChallenge` + `completeXrplAuth` for explicit
7011
+ * two-step XRPL login flow. This wrapper now expects `challenge` to include
7012
+ * the `session` and optional `public_key`.
7013
+ */
7014
+ public async loginWithXrplWallet(
6736
7015
  user: string,
6737
7016
  walletAddress: string,
6738
7017
  signature: string,
6739
7018
  challenge: string | XrplWalletChallengePayload,
6740
7019
  network = "xrpl",
6741
7020
  ): Promise<LoginResponse> {
6742
- return this.login(XRPL_WALLET_LOGIN_TYPE, {
6743
- user: user,
7021
+ let parsedChallenge: Partial<XrplWalletChallengePayload> | null = null;
7022
+ if (typeof challenge === "string") {
7023
+ try {
7024
+ parsedChallenge = JSON.parse(challenge) as Partial<XrplWalletChallengePayload>;
7025
+ } catch {
7026
+ throw new Error("XRPL challenge must be JSON with a session field");
7027
+ }
7028
+ } else {
7029
+ parsedChallenge = challenge;
7030
+ }
7031
+
7032
+ const session = parsedChallenge?.session;
7033
+ if (!session) {
7034
+ throw new Error("XRPL challenge payload is missing session; call getXrplAuthChallenge first");
7035
+ }
7036
+
7037
+ const response = await this.completeXrplAuth({
7038
+ user,
6744
7039
  identifier: {
6745
7040
  type: "m.id.user",
6746
- user: user,
7041
+ user,
6747
7042
  },
6748
- wallet_address: walletAddress,
6749
- signature: signature,
6750
- challenge: typeof challenge === "string" ? challenge : JSON.stringify(challenge),
6751
- network: network,
7043
+ session,
7044
+ address: walletAddress,
7045
+ signature,
7046
+ public_key: parsedChallenge?.public_key,
7047
+ network,
6752
7048
  });
7049
+ await this.applyLoginResponse(response, XRPL_WALLET_LOGIN_TYPE);
7050
+ return response;
6753
7051
  }
6754
7052
 
6755
7053
  /**