Skip to content

Commit 69b4c22

Browse files
committed
start on improving auth callback
1 parent 7275735 commit 69b4c22

File tree

6 files changed

+146
-80
lines changed

6 files changed

+146
-80
lines changed

packages/core/src/__clients__/core.ts

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import {
1818
v1HashFunction,
1919
v1Curve,
2020
v1PrivateKey,
21+
OtpAuthResult,
22+
OAuthAuthResult,
23+
WalletAuthResult,
24+
BaseAuthResult,
2125
} from "@turnkey/sdk-types";
2226
import {
2327
DEFAULT_SESSION_EXPIRATION_IN_SECONDS,
@@ -66,7 +70,11 @@ import {
6670
isSolanaProvider,
6771
getAuthenticatorAddresses,
6872
getCurveTypeFromProvider,
73+
<<<<<<< HEAD
6974
isValidPasskeyName,
75+
=======
76+
addressFromPublicKey,
77+
>>>>>>> d12cdedf (start on improving auth callback)
7078
} from "@utils";
7179
import { createStorageManager } from "../__storage__/base";
7280
import { CrossPlatformApiKeyStamper } from "../__stampers__/api/base";
@@ -311,7 +319,7 @@ export class TurnkeyClient {
311319
publicKey?: string;
312320
sessionKey?: string;
313321
expirationSeconds?: string;
314-
}): Promise<string> => {
322+
}): Promise<BaseAuthResult> => {
315323
let generatedPublicKey: string | undefined = undefined;
316324
return await withTurnkeyErrorHandling(
317325
async () => {
@@ -344,7 +352,7 @@ export class TurnkeyClient {
344352

345353
generatedPublicKey = undefined; // Key pair was successfully used, set to null to prevent cleanup
346354

347-
return sessionResponse.session;
355+
return { sessionToken: sessionResponse.session };
348356
},
349357
{
350358
errorMessage: "Unable to log in with the provided passkey",
@@ -397,7 +405,7 @@ export class TurnkeyClient {
397405
passkeyDisplayName?: string;
398406
expirationSeconds?: string;
399407
challenge?: string;
400-
}): Promise<string> => {
408+
}): Promise<BaseAuthResult> => {
401409
const {
402410
createSubOrgParams,
403411
passkeyDisplayName,
@@ -474,7 +482,7 @@ export class TurnkeyClient {
474482

475483
generatedPublicKey = undefined; // Key pair was successfully used, set to null to prevent cleanup
476484

477-
return sessionResponse.session;
485+
return { sessionToken: sessionResponse.session };
478486
},
479487
{
480488
errorCode: TurnkeyErrorCodes.PASSKEY_SIGNUP_AUTH_ERROR,
@@ -675,7 +683,7 @@ export class TurnkeyClient {
675683
publicKey?: string;
676684
sessionKey?: string;
677685
expirationSeconds?: string;
678-
}): Promise<string> => {
686+
}): Promise<WalletAuthResult> => {
679687
let publicKey =
680688
params.publicKey || (await this.apiKeyStamper?.createKeyPair());
681689
return withTurnkeyErrorHandling(
@@ -718,7 +726,15 @@ export class TurnkeyClient {
718726
sessionKey,
719727
});
720728

721-
return sessionResponse.session;
729+
// TODO (Moe): What happens if a user connects to MetaMask on Ethereum,
730+
// then switches to a Solana account within MetaMask? Will this flow break?
731+
return {
732+
sessionToken: sessionResponse.session,
733+
address: addressFromPublicKey(
734+
walletProvider.chainInfo.namespace,
735+
publicKey,
736+
),
737+
};
722738
},
723739
{
724740
errorMessage: "Unable to log in with the provided wallet",
@@ -765,7 +781,7 @@ export class TurnkeyClient {
765781
createSubOrgParams?: CreateSubOrgParams;
766782
sessionKey?: string;
767783
expirationSeconds?: string;
768-
}): Promise<string> => {
784+
}): Promise<WalletAuthResult> => {
769785
const {
770786
walletProvider,
771787
createSubOrgParams,
@@ -848,7 +864,15 @@ export class TurnkeyClient {
848864

849865
generatedPublicKey = undefined; // Key pair was successfully used, set to null to prevent cleanup
850866

851-
return sessionResponse.session;
867+
// TODO (Moe): What happens if a user connects to MetaMask on Ethereum,
868+
// then switches to a Solana account within MetaMask? Will this flow break?
869+
return {
870+
sessionToken: sessionResponse.session,
871+
address: addressFromPublicKey(
872+
walletProvider.chainInfo.namespace,
873+
publicKey,
874+
),
875+
};
852876
},
853877
{
854878
errorMessage: "Failed to sign up with wallet",
@@ -896,7 +920,7 @@ export class TurnkeyClient {
896920
createSubOrgParams?: CreateSubOrgParams;
897921
sessionKey?: string;
898922
expirationSeconds?: string;
899-
}): Promise<string> => {
923+
}): Promise<WalletAuthResult> => {
900924
const createSubOrgParams = params.createSubOrgParams;
901925
const sessionKey = params.sessionKey || SessionKey.DefaultSessionkey;
902926
const walletProvider = params.walletProvider;
@@ -1063,7 +1087,13 @@ export class TurnkeyClient {
10631087
sessionKey,
10641088
});
10651089

1066-
return sessionToken;
1090+
return {
1091+
sessionToken: sessionToken,
1092+
address: addressFromPublicKey(
1093+
walletProvider.chainInfo.namespace,
1094+
publicKey,
1095+
),
1096+
};
10671097
},
10681098
{
10691099
errorCode: TurnkeyErrorCodes.WALLET_LOGIN_OR_SIGNUP_ERROR,
@@ -1218,7 +1248,7 @@ export class TurnkeyClient {
12181248
publicKey?: string;
12191249
invalidateExisting?: boolean;
12201250
sessionKey?: string;
1221-
}): Promise<string> => {
1251+
}): Promise<OtpAuthResult> => {
12221252
const {
12231253
verificationToken,
12241254
invalidateExisting = false,
@@ -1254,7 +1284,10 @@ export class TurnkeyClient {
12541284
sessionKey,
12551285
});
12561286

1257-
return loginRes.session;
1287+
return {
1288+
sessionToken: loginRes.session,
1289+
verificationToken,
1290+
};
12581291
},
12591292
{
12601293
errorMessage: "Failed to log in with OTP",
@@ -1302,7 +1335,7 @@ export class TurnkeyClient {
13021335
createSubOrgParams?: CreateSubOrgParams;
13031336
invalidateExisting?: boolean;
13041337
sessionKey?: string;
1305-
}): Promise<string> => {
1338+
}): Promise<OtpAuthResult> => {
13061339
const {
13071340
verificationToken,
13081341
contact,
@@ -1377,7 +1410,7 @@ export class TurnkeyClient {
13771410
invalidateExisting?: boolean;
13781411
sessionKey?: string;
13791412
createSubOrgParams?: CreateSubOrgParams;
1380-
}): Promise<string> => {
1413+
}): Promise<OtpAuthResult> => {
13811414
const {
13821415
otpId,
13831416
otpCode,
@@ -1457,7 +1490,7 @@ export class TurnkeyClient {
14571490
sessionKey?: string;
14581491
invalidateExisting?: boolean;
14591492
createSubOrgParams?: CreateSubOrgParams;
1460-
}): Promise<string> => {
1493+
}): Promise<OAuthAuthResult> => {
14611494
const {
14621495
oidcToken,
14631496
publicKey,
@@ -1527,7 +1560,7 @@ export class TurnkeyClient {
15271560
publicKey: string;
15281561
invalidateExisting?: boolean;
15291562
sessionKey?: string;
1530-
}): Promise<string> => {
1563+
}): Promise<OAuthAuthResult> => {
15311564
const {
15321565
oidcToken,
15331566
invalidateExisting = false,
@@ -1569,7 +1602,7 @@ export class TurnkeyClient {
15691602
sessionKey,
15701603
});
15711604

1572-
return loginRes.session;
1605+
return { sessionToken: loginRes.session, oidcToken };
15731606
},
15741607
{
15751608
errorMessage: "Failed to complete OAuth login",
@@ -1621,7 +1654,7 @@ export class TurnkeyClient {
16211654
providerName: string;
16221655
createSubOrgParams?: CreateSubOrgParams;
16231656
sessionKey?: string;
1624-
}): Promise<string> => {
1657+
}): Promise<OAuthAuthResult> => {
16251658
const { oidcToken, publicKey, providerName, createSubOrgParams } = params;
16261659

16271660
return withTurnkeyErrorHandling(

packages/core/src/utils.ts

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -810,22 +810,36 @@ export function findWalletProviderFromAddress(
810810
return undefined;
811811
}
812812

813-
/**@internal */
814-
export function ethereumAddressFromCompressedPublicKey(publicKey: string) {
815-
const compressedBytes = uint8ArrayFromHexString(publicKey);
813+
/**
814+
* Derives a wallet address from a given public key and chain.
815+
*
816+
* @param chain - "ethereum" or "solana"
817+
* @param publicKey - The raw public key string
818+
* @returns The derived wallet address
819+
*/
820+
export function addressFromPublicKey(chain: Chain, publicKey: string): string {
821+
if (chain === Chain.Ethereum) {
822+
const compressedBytes = uint8ArrayFromHexString(publicKey);
816823

817-
const publicKeyUncompressed = uint8ArrayToHexString(
818-
uncompressRawPublicKey(compressedBytes, Curve.SECP256K1),
819-
);
824+
const publicKeyUncompressed = uint8ArrayToHexString(
825+
uncompressRawPublicKey(compressedBytes, Curve.SECP256K1),
826+
);
827+
828+
// drop 04 prefix
829+
const key = publicKeyUncompressed.startsWith("04")
830+
? publicKeyUncompressed.slice(2)
831+
: publicKeyUncompressed;
820832

821-
// drop 04 prefix
822-
const key = publicKeyUncompressed.startsWith("04")
823-
? publicKeyUncompressed.slice(2)
824-
: publicKeyUncompressed;
833+
// hash with Keccak256 and take last 20 bytes
834+
const hash = keccak256(uint8ArrayFromHexString(key));
835+
return "0x" + hash.slice(-40);
836+
}
837+
838+
if (chain === Chain.Solana) {
839+
return bs58.encode(uint8ArrayFromHexString(publicKey));
840+
}
825841

826-
// hash with Keccak256 and take last 20 bytes
827-
const hash = keccak256(uint8ArrayFromHexString(key));
828-
return "0x" + hash.slice(-40);
842+
throw new Error(`Unsupported chain: ${chain}`);
829843
}
830844

831845
/**@internal */
@@ -837,10 +851,10 @@ export function getAuthenticatorAddresses(user: v1User) {
837851
const { type, publicKey } = key.credential;
838852
switch (type) {
839853
case "CREDENTIAL_TYPE_API_KEY_SECP256K1":
840-
ethereum.push(ethereumAddressFromCompressedPublicKey(publicKey));
854+
ethereum.push(addressFromPublicKey(Chain.Ethereum, publicKey));
841855
break;
842856
case "CREDENTIAL_TYPE_API_KEY_ED25519":
843-
solana.push(bs58.encode(uint8ArrayFromHexString(publicKey)));
857+
solana.push(addressFromPublicKey(Chain.Solana, publicKey));
844858
break;
845859
}
846860
}

0 commit comments

Comments
 (0)