this repo has no description
1import React from "react";
2import { Text, View, StyleSheet, Button, Alert, TextInput } from "react-native";
3import {
4 digest,
5 getRandomValues,
6 createJwt,
7 generateJwk,
8 ReactNativeOAuthClient,
9} from "expo-atproto-auth";
10import { OAuthSession } from "@atproto/oauth-client";
11import { Agent } from "@atproto/api";
12import type { ReactNativeKey } from "expo-atproto-auth";
13import * as Browser from "expo-web-browser";
14
15const client = new ReactNativeOAuthClient({
16 clientMetadata: {
17 client_id: "https://hailey.at/oauth-client-metadata.json",
18 client_name: "React Native OAuth Client Demo",
19 client_uri: "https://hailey.at",
20 redirect_uris: ["at.hailey:/auth/callback"],
21 scope: "atproto transition:generic",
22 token_endpoint_auth_method: "none",
23 response_types: ["code"],
24 grant_types: ["authorization_code", "refresh_token"],
25 application_type: "native",
26 dpop_bound_access_tokens: true,
27 },
28 handleResolver: "https://bsky.social",
29});
30
31export default function App() {
32 const [values, setValues] = React.useState<Uint8Array>();
33 const [sha, setSha] = React.useState<Uint8Array>();
34 const [jwt, setJwt] = React.useState<string>();
35 const [privateJwk, setPrivateJwk] = React.useState<
36 ReactNativeKey | undefined
37 >();
38 const [session, setSession] = React.useState<OAuthSession>();
39 const [input, setInput] = React.useState<string>();
40 const [agent, setAgent] = React.useState<Agent>();
41
42 return (
43 <View style={styles.container}>
44 <Text>Current Account: {session ? session.did : "No Account"}</Text>
45 <Text>Values: {values}</Text>
46 <Button
47 title="Generate Random Values"
48 onPress={() => {
49 const newValues = getRandomValues(400);
50 setValues(newValues);
51 }}
52 />
53 <Text>SHA: {sha}</Text>
54 <Button
55 title="SHA from values"
56 onPress={() => {
57 if (!values) {
58 return;
59 }
60 let newSha: Uint8Array | undefined;
61 try {
62 newSha = digest(values, "sha256");
63 } catch (e: any) {
64 Alert.alert("Error", e.toString());
65 return;
66 }
67 setSha(newSha);
68 }}
69 />
70 <Text>JWT: {jwt}</Text>
71 <Button
72 title="Create JWT"
73 onPress={() => {
74 if (!privateJwk) {
75 return;
76 }
77
78 let newJwt: string | undefined;
79 try {
80 newJwt = createJwt("", "", privateJwk);
81 } catch (e: any) {
82 Alert.alert("Error", e.toString());
83 return;
84 }
85 setJwt(newJwt);
86 }}
87 />
88 <Text>Priv Key: {privateJwk?.kid}</Text>
89 <Button
90 title="Create JWK"
91 onPress={() => {
92 let newJwk: ReactNativeKey | undefined;
93 try {
94 newJwk = generateJwk("ES256");
95 } catch (e: any) {
96 Alert.alert("Error", e.toString());
97 return;
98 }
99 setPrivateJwk(newJwk);
100 }}
101 />
102
103 <TextInput
104 onChangeText={(t) => setInput(t)}
105 style={{ height: 40, width: 300, borderWidth: 1, padding: 5 }}
106 placeholder="Input"
107 autoCorrect={false}
108 />
109 <Button
110 title="Open Sign In"
111 onPress={async () => {
112 let url: URL;
113 try {
114 url = await client.authorize(input ?? "");
115 } catch (e: any) {
116 Alert.alert("Error", e.toString());
117 return;
118 }
119 const res = await Browser.openAuthSessionAsync(
120 url.toString(),
121 "at.hailey://auth/callback",
122 );
123
124 if (res.type === "success") {
125 const resUrl = new URL(res.url);
126 try {
127 const params = new URLSearchParams(resUrl.hash.substring(1));
128 const callbackRes = await client.callback(params);
129 setSession(callbackRes.session);
130
131 const agent = new Agent(callbackRes.session);
132 setAgent(agent);
133 } catch (e: any) {
134 Alert.alert("Error", e.toString());
135 }
136 } else {
137 Alert.alert("Error", `Received non-success status: ${res.type}`);
138 }
139 }}
140 />
141
142 <Button
143 title="Restore from DID"
144 onPress={async () => {
145 try {
146 const restoreRes = await client.restore(input ?? "");
147 setSession(restoreRes);
148
149 const agent = new Agent(restoreRes);
150 setAgent(agent);
151 } catch (e: any) {
152 Alert.alert("Error", e.toString());
153 }
154 }}
155 />
156
157 <Button
158 title="Get Profile"
159 onPress={async () => {
160 try {
161 const res = await agent?.getProfile({
162 actor: session?.did ?? "",
163 });
164 Alert.alert(
165 "Profile",
166 `Display Name: ${res?.data.displayName}, Bio: ${res?.data.description}`,
167 );
168 } catch (e: any) {
169 Alert.alert("Error", e.toString());
170 }
171 }}
172 disabled={!agent}
173 />
174
175 <Button
176 title="Create Post"
177 onPress={async () => {
178 try {
179 await agent?.post({
180 text: "Test post from Expo Atproto Auth example",
181 });
182 } catch (e: any) {
183 Alert.alert("Error", e.toString());
184 }
185 }}
186 disabled={!agent}
187 />
188 </View>
189 );
190}
191
192const styles = StyleSheet.create({
193 container: {
194 flex: 1,
195 alignItems: "center",
196 justifyContent: "center",
197 },
198});