Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@utxos/sdk",
"version": "0.1.0",
"version": "0.1.1",
"description": "UTXOS SDK - Web3 infrastructure platform for UTXO blockchains",
"main": "./dist/index.cjs",
"browser": "./dist/index.js",
Expand Down
53 changes: 53 additions & 0 deletions src/non-custodial/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,59 @@ export class Web3NonCustodialProvider {
};
}

/**
* Sends OTP to email address
* @param email - The email address to send OTP to
* @returns Promise that resolves when OTP is sent
*/
async sendEmailOtp(email: string): Promise<{ error: Error | null }> {
const res = await fetch(this.appOrigin + "/api/auth/email/send-otp", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, projectId: this.projectId }),
});

if (!res.ok) {
const data = await res.json();
return { error: new Error(data.error) };
}

return { error: null };
}

/**
* Verifies OTP and stores JWT (same pattern as OAuth callback)
* @param email - The email address used to send OTP
* @param code - The 6-digit OTP code
* @returns User data on success, error on failure
*/
async verifyEmailOtp(
email: string,
code: string,
): Promise<
| { data: Web3NonCustodialProviderUser; error: null }
| { data: null; error: Error }
> {
const res = await fetch(this.appOrigin + "/api/auth/email/verify-otp", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, code, projectId: this.projectId }),
});

if (!res.ok) {
const data = await res.json();
return { data: null, error: new Error(data.error) };
}

const { token } = await res.json();

// Store JWT same way as OAuth flow
await this.putInStorage<AuthJwtLocationObject>(AUTH_KEY, { jwt: token });

// Return user data same way as getUser()
return this.getUser();
}

private async putInStorage<ObjectType extends object>(
key: string,
data: ObjectType,
Expand Down
12 changes: 11 additions & 1 deletion src/types/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ export type Web3ProjectBranding = {
discordEnabled?: boolean;
googleEnabled?: boolean;
appleEnabled?: boolean;
emailEnabled?: boolean;
};

export type Web3ProjectWallet = {
id: string;
projectId: string;
key: string;
pubKeyHash: string;
stakeCredentialHash: string;
tags: string[];
};

export type Web3JWTBody = {
Expand All @@ -48,7 +58,7 @@ export type Web3JWTBody = {
username: string | null;
};

export type Web3AuthProvider = "google" | "discord" | "twitter" | "apple";
export type Web3AuthProvider = "google" | "discord" | "twitter" | "apple" | "email";

export type SponsorshipTxParserPostRequestBody = {
txHex: string;
Expand Down