-
Notifications
You must be signed in to change notification settings - Fork 327
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
[WIP] Project intergalactic - Fiat flow #4714
base: main
Are you sure you want to change the base?
Changes from 15 commits
8fd31f0
73faf7d
1338911
61cb684
fa27a96
020dbbf
9f28a9c
76943be
f24508f
e05d389
1a6a338
6049a4e
ac45d90
5142e8e
55246f8
8afb2c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,12 +4,19 @@ import { | |
TriangleDownIcon, | ||
} from "@radix-ui/react-icons"; | ||
import { useMemo } from "react"; | ||
import type { Chain } from "../../../../../../../chains/types.js"; | ||
import { getCachedChain } from "../../../../../../../chains/utils.js"; | ||
import type { ThirdwebClient } from "../../../../../../../client/client.js"; | ||
import { NATIVE_TOKEN_ADDRESS } from "../../../../../../../constants/addresses.js"; | ||
import { getContract } from "../../../../../../../contract/contract.js"; | ||
import { addSessionKey } from "../../../../../../../extensions/erc4337/account/addSessionKey.js"; | ||
import type { BuyWithFiatQuote } from "../../../../../../../pay/buyWithFiat/getQuote.js"; | ||
import type { BuyWithFiatStatus } from "../../../../../../../pay/buyWithFiat/getStatus.js"; | ||
import { getPayBaseUrl } from "../../../../../../../pay/utils/definitions.js"; | ||
import { formatNumber } from "../../../../../../../utils/formatNumber.js"; | ||
import { createAndSignUserOp } from "../../../../../../../wallets/smart/lib/userop.js"; | ||
import { hexlifyUserOp } from "../../../../../../../wallets/smart/lib/utils.js"; | ||
import { smartWallet } from "../../../../../../../wallets/smart/smart-wallet.js"; | ||
import { | ||
type Theme, | ||
fontSize, | ||
|
@@ -21,6 +28,8 @@ import { | |
useChainExplorers, | ||
useChainName, | ||
} from "../../../../../../core/hooks/others/useChainQuery.js"; | ||
import { useActiveAccount } from "../../../../../../core/hooks/wallets/useActiveAccount.js"; | ||
import { useSwitchActiveWalletChain } from "../../../../../../core/hooks/wallets/useSwitchActiveWalletChain.js"; | ||
import type { TokenInfo } from "../../../../../../core/utils/defaultTokens.js"; | ||
import { Spacer } from "../../../../components/Spacer.js"; | ||
import { Spinner } from "../../../../components/Spinner.js"; | ||
|
@@ -38,6 +47,7 @@ import { | |
import { getCurrencyMeta } from "./currencies.js"; | ||
|
||
export type BuyWithFiatPartialQuote = { | ||
intentId: string; | ||
fromCurrencySymbol: string; | ||
fromCurrencyAmount: string; | ||
onRampTokenAmount: string; | ||
|
@@ -77,6 +87,7 @@ export function fiatQuoteToPartialQuote( | |
name: quote.toToken.name, | ||
symbol: quote.toToken.symbol, | ||
}, | ||
intentId: quote.intentId, | ||
}; | ||
|
||
return data; | ||
|
@@ -90,6 +101,7 @@ export function FiatSteps(props: { | |
client: ThirdwebClient; | ||
step: number; | ||
onContinue: () => void; | ||
setOnRampLinkOverride?: (link: string) => void; | ||
}) { | ||
const statusMeta = props.status | ||
? getBuyWithFiatStatusMeta(props.status) | ||
|
@@ -102,8 +114,100 @@ export function FiatSteps(props: { | |
fromCurrencySymbol, | ||
fromCurrencyAmount, | ||
toTokenAmount, | ||
intentId, | ||
} = props.partialQuote; | ||
|
||
const account = useActiveAccount(); | ||
const switchChain = useSwitchActiveWalletChain(); | ||
|
||
const deploySmartWallet = async ({ chain }: { chain: Chain }) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. needs to be better organized |
||
if (!account) return; | ||
|
||
await switchChain(chain); | ||
|
||
const smartWalletHandle = smartWallet({ | ||
chain, | ||
sponsorGas: true, | ||
}); | ||
|
||
const smartAccount = await smartWalletHandle.connect({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right now, this creates a smart wallet that is deterministic to the account, but not per intent. How can I send in an intentId as the string to be deterministic by? |
||
client: props.client, | ||
personalAccount: account, | ||
}); | ||
console.log("smartAccount", smartAccount); | ||
|
||
const smartAccountContract = getContract({ | ||
client: props.client, | ||
chain, | ||
address: smartAccount.address, | ||
}); | ||
|
||
console.log("onRampTokenAmount", props.partialQuote.onRampTokenAmount); | ||
const sessionKeyTx = addSessionKey({ | ||
contract: smartAccountContract, | ||
account: account, | ||
// TODO: Env var this. | ||
// // prod | ||
// sessionKeyAddress: "0x1629Ce9Df01B10E7CF8837f559037A49d983aA10", // pay engine backend wallet | ||
// dev | ||
sessionKeyAddress: "0x32DC86f866e9F5Ed59A60b18c3B0f9b972a928F0", // dev engine backend wallet | ||
permissions: { | ||
approvedTargets: "*", // the addresses of allowed contracts, or '*' for any contract | ||
permissionStartTimestamp: new Date(), // the date when the session key becomes active | ||
permissionEndTimestamp: new Date(Date.now() + 24 * 60 * 60 * 1000), // the date when the session key expires | ||
// TODO: Perhaps add a buffer here to be safe? | ||
nativeTokenLimitPerTransaction: props.partialQuote.onRampTokenAmount, | ||
}, | ||
}); | ||
|
||
const signedUserOp = await createAndSignUserOp({ | ||
transactions: [sessionKeyTx], | ||
adminAccount: account, | ||
client: props.client, | ||
smartWalletOptions: { | ||
chain, | ||
sponsorGas: true, | ||
}, | ||
}); | ||
|
||
const hexlifiedUserOp = hexlifyUserOp(signedUserOp); | ||
console.log("signedUserOp", signedUserOp); | ||
console.log("hexlifiedUserOp", hexlifiedUserOp); | ||
console.log("sessionKeyTx", sessionKeyTx); | ||
|
||
console.log("chainId", chain.id); | ||
console.log("intentId", intentId); | ||
console.log("toAddress", account.address); | ||
const response = await fetch( | ||
`${getPayBaseUrl()}/v2/intent-wallets/deploy`, | ||
{ | ||
method: "POST", | ||
body: JSON.stringify({ | ||
chainId: chain.id, | ||
intentId: intentId, | ||
intentType: "buyWithFiat", | ||
signedUserOps: [hexlifiedUserOp], | ||
toAddress: account.address, | ||
smartWalletAddress: smartAccount.address, | ||
}), | ||
headers: { | ||
"Content-Type": "application/json", | ||
"x-client-id": process.env.NEXT_PUBLIC_THIRDWEB_CLIENT_ID as string, | ||
}, | ||
}, | ||
); | ||
|
||
const data = await response.json(); | ||
console.log("response from server", data); | ||
|
||
props.setOnRampLinkOverride?.(data.onRampLink); | ||
|
||
return { | ||
smartWalletAddress: smartAccount.address, | ||
userAddress: account.address, | ||
}; | ||
}; | ||
|
||
const currency = getCurrencyMeta(fromCurrencySymbol); | ||
const isPartialSuccess = statusMeta?.progressStatus === "partialSuccess"; | ||
|
||
|
@@ -313,6 +417,10 @@ export function FiatSteps(props: { | |
<Spacer y="lg" /> | ||
|
||
{/* Step 1 */} | ||
<button onClick={() => deploySmartWallet({ chain: onRampChain })}> | ||
Deploy smart wallet with session key | ||
</button> | ||
|
||
<PaymentStep | ||
title={ | ||
<Text color="primaryText" size="md"> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,7 @@ type DomainOverrides = { | |
bundler?: string; | ||
}; | ||
|
||
export const DEFAULT_RPC_URL = "rpc.thirdweb.com"; | ||
export const DEFAULT_RPC_URL = "rpc.thirdweb-dev.com"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change back |
||
const DEFAULT_SOCIAL_URL = "social.thirdweb.com"; | ||
const DEFAULT_IN_APP_WALLET_URL = "embedded-wallet.thirdweb.com"; | ||
const DEFAULT_PAY_URL = "pay.thirdweb.com"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove before merging