Skip to content

Commit

Permalink
Fee Options (#15)
Browse files Browse the repository at this point in the history
* Native TX fee options

* Add Fee Options for Native Transfer and ERC20

* Add Fee Options to all operations use SendXXXArgs to Transaction converters

* Use erc20, erc712, erc1155, delayedEncode functions in SendTransactionArgs.transactions

* bump sequence.js/waas
  • Loading branch information
marino39 authored Apr 9, 2024
1 parent d2da3b8 commit 0d5490d
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 41 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@0xsequence/design-system": "^1.0.13",
"@0xsequence/indexer": "^1.9.8",
"@0xsequence/network": "^1.9.8",
"@0xsequence/waas": "^1.9.8",
"@0xsequence/waas": "^1.9.16",
"@react-oauth/google": "^0.11.1",
"@vanilla-extract/css": "^1.12.0",
"axios": "^1.6.0",
Expand Down
59 changes: 54 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

87 changes: 74 additions & 13 deletions src/components/views/CallContractsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
import { Box, Text, Button, TextInput, Spinner } from "@0xsequence/design-system"
import { SetStateAction, useState } from "react"
import { sequence } from "../../main"
import { isSentTransactionResponse, Network } from "@0xsequence/waas"
import {
delayedEncode,
FeeOption,
isSentTransactionResponse,
Network,
} from "@0xsequence/waas"
import { checkTransactionFeeOptions, TransactionFeeOptions } from "./TransactionFeeOptions.tsx";

export function CallContractsView(props: {network?: Network}) {
const [contractAddress, setContractAddress] = useState<string>('')
Expand All @@ -13,6 +19,35 @@ export function CallContractsView(props: {network?: Network}) {
const [inProgress, setInProgress] = useState<boolean>(false)
const [sendTransactionError, setSendTransactionError] = useState<string>()

const [feeOptions, setFeeOptions] = useState<FeeOption[]>()
const [feeOption, setFeeOption] = useState<FeeOption>()
const [feeQuote, setFeeQuote] = useState<string>()
const [feeSponsored, setFeeSponsored] = useState<boolean>(false)

const checkFeeOptions = async () => {
const resp = await checkTransactionFeeOptions({
transactions: [delayedEncode({
to: contractAddress,
abi: contractAbi,
func: contractMethod,
args: JSON.parse(contractMethodArgs),
value: "0"
})],
network: props.network
})

if (resp.feeQuote && resp.feeOptions) {
setFeeOptions(resp.feeOptions)
setFeeQuote(resp.feeQuote)

console.log('feeOptions', resp)
return
}

setFeeSponsored(true)
console.log('tx sponsored')
}

const callContract = async () => {
try {
setSendTransactionError(undefined)
Expand All @@ -24,7 +59,9 @@ export function CallContractsView(props: {network?: Network}) {
abi: contractAbi,
func: contractMethod,
args: JSON.parse(contractMethodArgs),
value: 0
value: 0,
transactionsFeeOption: feeOption,
transactionsFeeQuote: feeQuote
})

if (isSentTransactionResponse(tx)) {
Expand Down Expand Up @@ -94,23 +131,47 @@ export function CallContractsView(props: {network?: Network}) {
data-id="nativeTokenSendAmount"
/>
</Box>

<TransactionFeeOptions feeOptions={feeOptions} onSelected={setFeeOption}/>
{ feeSponsored && (
<Box marginTop="5">
<Text variant="normal" fontWeight="bold">
Fee options: Tx Sponsored!
</Text>
</Box>
)}

{sendTransactionError && (
<Box marginTop="3">
Transaction failed: {sendTransactionError}
</Box>
)}
{!inProgress ? (
<Button
marginTop="5"
label="Call contract"
disabled={
contractAddress === '' &&
contractAbi === '' &&
contractMethod === '' &&
contractMethodArgs === ''
}
onClick={() => callContract() }
/>
<Box>
<Button
marginTop="5"
marginRight="2"
label="Check fee options"
disabled={
contractAddress === '' &&
contractAbi === '' &&
contractMethod === '' &&
contractMethodArgs === ''
}
onClick={() => checkFeeOptions()}
/>
<Button
marginTop="5"
label="Call contract"
disabled={
contractAddress === '' &&
contractAbi === '' &&
contractMethod === '' &&
contractMethodArgs === ''
}
onClick={() => callContract() }
/>
</Box>
) : (
<Box gap="2" marginY="4" alignItems="center" justifyContent="center">
<Spinner />
Expand Down
65 changes: 58 additions & 7 deletions src/components/views/SendERC1155View.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { useEffect, useState } from 'react'
import { Box, Text, Button, TextInput, Spinner, Select } from "@0xsequence/design-system"
import { ethers } from "ethers"
import { sequence } from '../../main'
import { isSentTransactionResponse, Network } from '@0xsequence/waas'
import { erc1155, FeeOption, isSentTransactionResponse, Network } from '@0xsequence/waas'
import { GetTokenBalancesReturn, SequenceIndexer } from '@0xsequence/indexer'
import { checkTransactionFeeOptions, TransactionFeeOptions } from "./TransactionFeeOptions.tsx";

const INDEXER_API_KEY = import.meta.env.VITE_SEQUENCE_INDEXER_API_KEY

Expand Down Expand Up @@ -82,6 +83,11 @@ export function SendERC1155View(props: {network?: Network}) {
const [isLoading, setIsLoading] = useState<boolean>(false)
const [options, setOptions] = useState<GetTokenBalancesReturn | undefined>(undefined)

const [feeOptions, setFeeOptions] = useState<FeeOption[]>()
const [feeOption, setFeeOption] = useState<FeeOption>()
const [feeQuote, setFeeQuote] = useState<string>()
const [feeSponsored, setFeeSponsored] = useState<boolean>(false)

const addTokenEntry = () => {
setTokenEntries([...tokenEntries, { tokenId: '', amount: '' }])
}
Expand Down Expand Up @@ -132,6 +138,31 @@ export function SendERC1155View(props: {network?: Network}) {
setTokenEntries(newEntries)
}

const checkFeeOptions = async () => {
const resp = await checkTransactionFeeOptions({
transactions: [erc1155({
to: destinationAddress,
token: tokenAddress,
values: tokenEntries.map((entry) => ({
id: entry.tokenId,
amount: ethers.utils.parseUnits(entry.amount, 0)
})),
})],
network: props.network,
})

if (resp.feeQuote && resp.feeOptions) {
setFeeOptions(resp.feeOptions)
setFeeQuote(resp.feeQuote)

console.log('feeOptions', resp)
return
}

setFeeSponsored(true)
console.log('tx sponsored')
}

const sendTokens = async () => {
try {
setError('')
Expand All @@ -144,7 +175,9 @@ export function SendERC1155View(props: {network?: Network}) {
id: entry.tokenId,
amount: ethers.utils.parseUnits(entry.amount, 0)
})),
network: props.network?.id
network: props.network?.id,
transactionsFeeOption: feeOption,
transactionsFeeQuote: feeQuote
})

if (isSentTransactionResponse(tx)) {
Expand Down Expand Up @@ -200,12 +233,30 @@ export function SendERC1155View(props: {network?: Network}) {
</Box>
)}

<TransactionFeeOptions feeOptions={feeOptions} onSelected={setFeeOption}/>
{ feeSponsored && (
<Box marginTop="5">
<Text variant="normal" fontWeight="bold">
Fee options: Tx Sponsored!
</Text>
</Box>
)}

{!isLoading ? (
<Button
marginTop="5"
label="Send Tokens"
onClick={sendTokens}
/>
<Box>
<Button
marginTop="5"
marginRight="2"
label="Check fee options"
disabled={tokenAddress === '' && destinationAddress === '' && tokenEntries.length !== 0}
onClick={() => checkFeeOptions()}
/>
<Button
marginTop="5"
label="Send Tokens"
onClick={sendTokens}
/>
</Box>
) : (
<Box gap="2" marginY="4" alignItems="center" justifyContent="center">
<Spinner />
Expand Down
Loading

0 comments on commit 0d5490d

Please sign in to comment.