Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: use resolveAddress instead of connectedAddress #526

Merged
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
4 changes: 3 additions & 1 deletion packages/debugger/app/components/cast-composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,9 @@ function CastEmbedPreview({ onRemove, url }: CastEmbedPreviewProps) {
const farcasterIdentity = useFarcasterIdentity();
const frame = useFrame_unstable({
frameStateHook: useDebuggerFrameState,
connectedAddress: account.address,
async resolveAddress() {
return account.address ?? null;
},
homeframeUrl: url,
frameActionProxy: "/frames",
frameGetProxy: "/frames",
Expand Down
15 changes: 8 additions & 7 deletions packages/render/src/unstable-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import type {
FrameGETRequest,
FramePOSTRequest,
FrameRequest,
OnConnectWalletFunc,
OnMintArgs,
OnSignatureFunc,
OnTransactionFunc,
Expand Down Expand Up @@ -49,6 +48,8 @@ export type ResolveSignerFunction = (
arg: ResolveSignerFunctionArg
) => ResolvedSigner;

export type ResolveAddressFunction = () => Promise<`0x${string}` | null>;

export type UseFrameOptions<
TExtraDataPending = unknown,
TExtraDataDone = unknown,
Expand Down Expand Up @@ -103,9 +104,13 @@ export type UseFrameOptions<
*/
frame?: ParseFramesWithReportsResult | null;
/**
* connected wallet address of the user, send to the frame for transaction requests
* Called before onTransaction/onSignature is invoked to obtain an address to use.
*
* If the function returns null onTransaction/onSignature will not be called.
*
* Sent to the frame on transaction requests.
*/
connectedAddress: `0x${string}` | undefined;
resolveAddress: ResolveAddressFunction;
/** a function to handle mint buttons */
onMint?: (t: OnMintArgs) => void;
/** a function to handle transaction buttons that returned transaction data from the target, returns the transaction hash or null */
Expand All @@ -114,10 +119,6 @@ export type UseFrameOptions<
transactionDataSuffix?: `0x${string}`;
/** A function to handle transaction buttons that returned signature data from the target, returns signature hash or null */
onSignature?: OnSignatureFunc;
/**
* Called when user presses transaction button but there is no wallet connected.
*/
onConnectWallet?: OnConnectWalletFunc;
/**
* Extra data appended to the frame action payload
*/
Expand Down
92 changes: 51 additions & 41 deletions packages/render/src/unstable-use-frame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import type { UseFrameOptions, UseFrameReturnValue } from "./unstable-types";
import { useFrameState } from "./unstable-use-frame-state";
import { useFetchFrame } from "./unstable-use-fetch-frame";
import { useFreshRef } from "./hooks/use-fresh-ref";
import { tryCallAsync } from "./helpers";

function onErrorFallback(e: Error): void {
console.error("@frames.js/render", e);
}

function onMintFallback({ target }: OnMintArgs): void {
console.log("Please provide your own onMint function to useFrame() hook.");
Expand All @@ -28,7 +33,7 @@ function onMintFallback({ target }: OnMintArgs): void {
}
}

function onConnectWalletFallback(): never {
function resolveAddressFallback(): never {
throw new Error(
"Please implement this function in order to use transactions"
);
Expand Down Expand Up @@ -131,6 +136,13 @@ function validateLinkButtonTarget(target: string): boolean {
return true;
}

function defaultFetchFunction(
input: RequestInfo | URL,
init?: RequestInit
): Promise<Response> {
return fetch(input, init);
}

export type {
UseFrameReturnValue as UnstableUseFrameReturnValue,
UseFrameOptions as UnstableUseFrameOptions,
Expand All @@ -149,20 +161,19 @@ export function useFrame_unstable<
onMint = onMintFallback,
onTransaction = onTransactionFallback,
transactionDataSuffix,
onConnectWallet = onConnectWalletFallback,
onSignature = onSignatureFallback,
connectedAddress,
resolveAddress = resolveAddressFallback,
frame,
/** Ex: /frames */
frameActionProxy,
/** Ex: /frames */
frameGetProxy,
extraButtonRequestPayload,
resolveSigner: resolveSpecification,
onError,
onError = onErrorFallback,
onLinkButtonClick = handleLinkButtonClickFallback,
onRedirect = handleRedirectFallback,
fetchFn = (...args) => fetch(...args),
fetchFn = defaultFetchFunction,
onTransactionDataError,
onTransactionDataStart,
onTransactionDataSuccess,
Expand Down Expand Up @@ -246,15 +257,22 @@ export function useFrame_unstable<
true
)
.catch((e) => {
console.error(e);
onErrorRef.current(e instanceof Error ? e : new Error(String(e)));
});
} else {
resetFrameState({
homeframeUrl,
parseResult: frame,
});
}
}, [frame, homeframeUrl, clearFrameState, fetchFrameRef, resetFrameState]);
}, [
frame,
homeframeUrl,
clearFrameState,
fetchFrameRef,
resetFrameState,
onErrorRef,
]);

const onPostButton = useCallback(
async function onPostButton({
Expand All @@ -281,8 +299,7 @@ export function useFrame_unstable<
"Cannot perform post/post_redirect without a frame"
);

console.error(`@frames.js/render: ${error.message}`);
onErrorRef.current?.(error);
onErrorRef.current(error);

return;
}
Expand Down Expand Up @@ -314,8 +331,7 @@ export function useFrame_unstable<
[fetchFrameRef, frameStateRef, onErrorRef]
);

const onConnectWalletRef = useFreshRef(onConnectWallet);
const connectedAddressRef = useFreshRef(connectedAddress);
const resolveAddressRef = useFreshRef(resolveAddress);

const onTransactionButton = useCallback(
async function onTransactionButton({
Expand All @@ -334,8 +350,7 @@ export function useFrame_unstable<
if (currentState.type === "not-initialized") {
const error = new Error("Cannot perform transaction without a frame");

console.error(`@frames.js/render: ${error.message}`);
onErrorRef.current?.(error);
onErrorRef.current(error);

return;
}
Expand All @@ -346,25 +361,28 @@ export function useFrame_unstable<
return;
}

if (!connectedAddressRef.current) {
try {
onConnectWalletRef.current();
} catch (e) {
onErrorRef.current?.(e instanceof Error ? e : new Error(String(e)));
console.error(`@frames.js/render: ${String(e)}`);
}
const addressOrError = await tryCallAsync(() =>
resolveAddressRef.current()
);

if (addressOrError instanceof Error) {
onErrorRef.current(addressOrError);
return;
}

if (!addressOrError) {
onErrorRef.current(
new Error(
"Wallet address missing, please check resolveAddress() function passed to useFrame_unstable() hook."
)
);
return;
}

// transaction request always requires address
const frameContext = {
...currentState.frameContext,
address:
"address" in currentState.frameContext &&
typeof currentState.frameContext.address === "string"
? currentState.frameContext.address
: connectedAddressRef.current,
address: addressOrError,
};

await fetchFrameRef.current({
Expand All @@ -376,7 +394,7 @@ export function useFrame_unstable<
inputText: postInputText,
signer: currentState.signerState.signer,
frameContext,
address: connectedAddressRef.current,
address: addressOrError,
url: currentState.homeframeUrl,
target: frameButton.target,
frameButton,
Expand All @@ -386,13 +404,7 @@ export function useFrame_unstable<
sourceFrame: currentFrame,
});
},
[
frameStateRef,
connectedAddressRef,
fetchFrameRef,
onErrorRef,
onConnectWalletRef,
]
[frameStateRef, fetchFrameRef, onErrorRef, resolveAddressRef]
);

const onButtonPress = useCallback(
Expand All @@ -408,7 +420,7 @@ export function useFrame_unstable<
validateLinkButtonTarget(frameButton.target);
} catch (error) {
if (error instanceof Error) {
onErrorRef.current?.(error);
onErrorRef.current(error);
}
return;
}
Expand Down Expand Up @@ -446,15 +458,15 @@ export function useFrame_unstable<
homeframeUrl;

if (!target) {
onErrorRef.current?.(new Error(`Missing target`));
onErrorRef.current(new Error(`Missing target`));
return;
}

try {
validateLinkButtonTarget(target);
} catch (error) {
if (error instanceof Error) {
onErrorRef.current?.(error);
onErrorRef.current(error);
}
return;
}
Expand All @@ -479,11 +491,9 @@ export function useFrame_unstable<
});
setInputText("");
} catch (err) {
if (err instanceof Error) {
onErrorRef.current?.(err);
}

console.error(err);
onErrorRef.current(
err instanceof Error ? err : new Error(String(err))
);
}
break;
}
Expand Down
5 changes: 2 additions & 3 deletions packages/render/src/use-composer-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import type {
} from "./mini-app-messages";
import { miniAppMessageSchema } from "./mini-app-messages";
import type { FarcasterSigner } from "./identity/farcaster";
import type { ResolveAddressFunction } from "./unstable-types";

export type { MiniAppMessage, MiniAppResponse };
export type { MiniAppMessage, MiniAppResponse, ResolveAddressFunction };

type FetchComposerActionFunctionArg = {
actionState: ComposerActionState;
Expand Down Expand Up @@ -68,8 +69,6 @@ export type OnCreateCastFunction = (arg: {
cast: ComposerActionState;
}) => Promise<void>;

export type ResolveAddressFunction = () => Promise<`0x${string}` | null>;

export type OnMessageRespondFunction = (
response: MiniAppResponse,
form: ComposerActionFormResponse
Expand Down
Loading