@farcaster/frame-sdk 0.0.59 → 0.0.61
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.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.min.js +8 -8
- package/dist/index.min.js.map +4 -4
- package/dist/quickAuth.d.ts +42 -0
- package/dist/quickAuth.js +74 -0
- package/dist/sdk.js +5 -31
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +4 -14
- package/package.json +3 -3
- package/src/index.ts +4 -0
- package/src/quickAuth.ts +148 -0
- package/src/sdk.ts +5 -38
- package/src/types.ts +4 -14
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { SignIn } from '@farcaster/frame-core';
|
|
2
|
+
export declare namespace getToken {
|
|
3
|
+
type Options = {
|
|
4
|
+
/**
|
|
5
|
+
* Use a custom Quick Auth server, otherwise defaults to the public
|
|
6
|
+
* instance provided by Farcaster.
|
|
7
|
+
*
|
|
8
|
+
* @default https://auth.farcaster.xyz
|
|
9
|
+
*/
|
|
10
|
+
quickAuthServerOrigin?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Acquire a new token even if one is already in memory and not expired.
|
|
13
|
+
*
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
force?: string;
|
|
17
|
+
};
|
|
18
|
+
type ReturnValue = {
|
|
19
|
+
token: string;
|
|
20
|
+
};
|
|
21
|
+
type ReturnType = Promise<ReturnValue>;
|
|
22
|
+
type ErrorType = SignIn.RejectedByUser | Error;
|
|
23
|
+
}
|
|
24
|
+
export type QuickAuth = {
|
|
25
|
+
/**
|
|
26
|
+
* Returns the session token if one is present and not expired.
|
|
27
|
+
*/
|
|
28
|
+
readonly token: string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Get a Quick Auth JWT.
|
|
31
|
+
*
|
|
32
|
+
* If a token is already in memory and not expired it will be returned unless
|
|
33
|
+
* `force` is used. Otherwise a new token will be acquired.
|
|
34
|
+
*/
|
|
35
|
+
getToken: (options?: getToken.Options) => getToken.ReturnType;
|
|
36
|
+
/**
|
|
37
|
+
* Make an authenticated fetch request. The `Authorization` header will
|
|
38
|
+
* contain `Bearer ${token}` where token is a Quick Auth session token.
|
|
39
|
+
*/
|
|
40
|
+
fetch: typeof fetch;
|
|
41
|
+
};
|
|
42
|
+
export declare const quickAuth: QuickAuth;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { SignIn } from '@farcaster/frame-core';
|
|
2
|
+
import { decodeJwt } from '@farcaster/quick-auth/decodeJwt';
|
|
3
|
+
import { createLightClient } from '@farcaster/quick-auth/light';
|
|
4
|
+
import * as Siwe from 'ox/Siwe';
|
|
5
|
+
import { frameHost } from './frameHost.js';
|
|
6
|
+
export const quickAuth = (() => {
|
|
7
|
+
let current;
|
|
8
|
+
let pendingPromise = undefined;
|
|
9
|
+
async function getTokenInner(options) {
|
|
10
|
+
const quickAuthClient = createLightClient({
|
|
11
|
+
origin: options.quickAuthServerOrigin,
|
|
12
|
+
});
|
|
13
|
+
const { nonce } = await quickAuthClient.generateNonce();
|
|
14
|
+
const response = await frameHost.signIn({
|
|
15
|
+
nonce,
|
|
16
|
+
acceptAuthAddress: true,
|
|
17
|
+
});
|
|
18
|
+
if (response.result) {
|
|
19
|
+
const parsedSiwe = Siwe.parseMessage(response.result.message);
|
|
20
|
+
// The Farcaster Client rendering the Mini App will set the domain
|
|
21
|
+
// based on the URL it's rendering. It should always be set.
|
|
22
|
+
if (!parsedSiwe.domain) {
|
|
23
|
+
throw new Error('Missing domain on SIWE message');
|
|
24
|
+
}
|
|
25
|
+
const verifyResult = await quickAuthClient.verifySiwf({
|
|
26
|
+
domain: parsedSiwe.domain,
|
|
27
|
+
message: response.result.message,
|
|
28
|
+
signature: response.result.signature,
|
|
29
|
+
});
|
|
30
|
+
current = {
|
|
31
|
+
token: verifyResult.token,
|
|
32
|
+
payload: decodeJwt(verifyResult.token),
|
|
33
|
+
};
|
|
34
|
+
return verifyResult;
|
|
35
|
+
}
|
|
36
|
+
if (response.error.type === 'rejected_by_user') {
|
|
37
|
+
throw new SignIn.RejectedByUser();
|
|
38
|
+
}
|
|
39
|
+
throw new Error('Unreachable');
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
get token() {
|
|
43
|
+
if (current &&
|
|
44
|
+
new Date(current.payload.exp * 1000) > new Date(Date.now() + 15000)) {
|
|
45
|
+
return current.token;
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
},
|
|
49
|
+
async getToken(options = {}) {
|
|
50
|
+
const force = options.force ?? false;
|
|
51
|
+
if (current &&
|
|
52
|
+
!force &&
|
|
53
|
+
new Date(current.payload.exp * 1000) > new Date(Date.now() + 15000)) {
|
|
54
|
+
return { token: current.token };
|
|
55
|
+
}
|
|
56
|
+
if (!pendingPromise) {
|
|
57
|
+
pendingPromise = getTokenInner(options);
|
|
58
|
+
}
|
|
59
|
+
pendingPromise.finally(() => {
|
|
60
|
+
pendingPromise = undefined;
|
|
61
|
+
});
|
|
62
|
+
return pendingPromise;
|
|
63
|
+
},
|
|
64
|
+
async fetch(url, options) {
|
|
65
|
+
const { token } = await this.getToken();
|
|
66
|
+
const headers = new Headers(options?.headers);
|
|
67
|
+
headers.set('Authorization', `Bearer ${token}`);
|
|
68
|
+
return fetch(url, {
|
|
69
|
+
...options,
|
|
70
|
+
headers,
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
})();
|
package/dist/sdk.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { AddMiniApp, SignIn, } from '@farcaster/frame-core';
|
|
2
|
-
import { createLightClient } from '@farcaster/quick-auth/light';
|
|
3
|
-
import * as Siwe from 'ox/Siwe';
|
|
4
2
|
import { createBack } from "./back.js";
|
|
5
3
|
import { ethereumProvider, getEthereumProvider } from "./ethereumProvider.js";
|
|
6
4
|
import { frameHost } from "./frameHost.js";
|
|
5
|
+
import { quickAuth } from "./quickAuth.js";
|
|
7
6
|
import { emitter } from "./sdkEmitter.js";
|
|
8
7
|
import { getSolanaProvider } from "./solanaProvider.js";
|
|
9
8
|
let cachedIsInMiniAppResult = null;
|
|
@@ -42,33 +41,6 @@ async function isInMiniApp(timeoutMs = 50) {
|
|
|
42
41
|
}
|
|
43
42
|
return isInMiniApp;
|
|
44
43
|
}
|
|
45
|
-
const quickAuth = async (options = {}) => {
|
|
46
|
-
const quickAuthClient = createLightClient({
|
|
47
|
-
origin: options.quickAuthServerOrigin,
|
|
48
|
-
});
|
|
49
|
-
const { nonce } = await quickAuthClient.generateNonce();
|
|
50
|
-
const response = await frameHost.signIn({
|
|
51
|
-
nonce,
|
|
52
|
-
acceptAuthAddress: true,
|
|
53
|
-
});
|
|
54
|
-
if (response.result) {
|
|
55
|
-
const parsedSiwe = Siwe.parseMessage(response.result.message);
|
|
56
|
-
// The Farcaster Client rendering the Mini App will set the domain
|
|
57
|
-
// based on the URL it's rendering. It should always be set.
|
|
58
|
-
if (!parsedSiwe.domain) {
|
|
59
|
-
throw new Error('Missing domain on SIWE message');
|
|
60
|
-
}
|
|
61
|
-
return await quickAuthClient.verifySiwf({
|
|
62
|
-
domain: parsedSiwe.domain,
|
|
63
|
-
message: response.result.message,
|
|
64
|
-
signature: response.result.signature,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
if (response.error.type === 'rejected_by_user') {
|
|
68
|
-
throw new SignIn.RejectedByUser();
|
|
69
|
-
}
|
|
70
|
-
throw new Error('Unreachable');
|
|
71
|
-
};
|
|
72
44
|
const addMiniApp = async () => {
|
|
73
45
|
const response = await frameHost.addFrame();
|
|
74
46
|
if (response.result) {
|
|
@@ -89,6 +61,7 @@ export const sdk = {
|
|
|
89
61
|
isInMiniApp,
|
|
90
62
|
context: frameHost.context,
|
|
91
63
|
back: createBack({ frameHost, emitter }),
|
|
64
|
+
quickAuth,
|
|
92
65
|
actions: {
|
|
93
66
|
setPrimaryButton: frameHost.setPrimaryButton.bind(frameHost),
|
|
94
67
|
ready: async (options = {}) => {
|
|
@@ -119,11 +92,12 @@ export const sdk = {
|
|
|
119
92
|
viewToken: frameHost.viewToken.bind(frameHost),
|
|
120
93
|
sendToken: frameHost.sendToken.bind(frameHost),
|
|
121
94
|
swapToken: frameHost.swapToken.bind(frameHost),
|
|
122
|
-
quickAuth,
|
|
123
95
|
},
|
|
124
96
|
experimental: {
|
|
125
97
|
getSolanaProvider,
|
|
126
|
-
quickAuth
|
|
98
|
+
quickAuth(options) {
|
|
99
|
+
return quickAuth.getToken(options);
|
|
100
|
+
},
|
|
127
101
|
},
|
|
128
102
|
wallet: {
|
|
129
103
|
ethProvider: ethereumProvider,
|