diff --git a/.env b/.env index 8543d9403..6e6a2b9a3 100644 --- a/.env +++ b/.env @@ -31,7 +31,7 @@ TS_PUBLIC_TYPESENSE_API_URL=https://typesense.tradingstrategy.ai TS_PUBLIC_TYPESENSE_API_KEY=npdPPJNELDhdr7v6IS9rQUpFG2VvdyAL TS_PUBLIC_DISCORD_URL=https://discord.gg/5M88m9nM8H TS_PUBLIC_WALLET_CONNECT_PROJECT_ID=9ee7efad98897eb60ba023db6aa72355 -TS_PUBLIC_STRATEGIES='[{"id":"enzyme-polygon-matic-eth-usdc","name":"ETH-MATIC-USDC momentum","url":"https://enzyme-polygon-matic-eth-usdc.tradingstrategy.ai","frontpage":true},{"id":"enzyme-arbitrum-eth-btc-rsi","name":"ETH-BTC price surge (Arbitrum)","url":"https://enzyme-arbitrum-eth-btc-rsi.tradingstrategy.ai/","depositOnEnzyme":true,"frontpage":true},{"id":"enzyme-polygon-eth-rolling-ratio","name":"ETH/BTC rolling ratio","url":"https://enzyme-polygon-eth-rolling-ratio.tradingstrategy.ai/","frontpage":true},{"id":"enzyme-polygon-eth-btc-rsi","name":"ETH-BTC price surge","url":"https://enzyme-polygon-eth-btc-rsi.tradingstrategy.ai/","frontpage":true,"hiddenPositions":[4]},{"id":"enzyme-ethereum-btc-eth-stoch-rsi","name":"Stochastic ETH/BTC long","url":"https://enzyme-ethereum-btc-eth-stoch-rsi.tradingstrategy.ai","frontpage":true},{"id":"enzyme-polygon-eth-btc-usdc","name":"ETH-BTC-USDC momentum","url":"https://enzyme-polygon-eth-btc-usdc.tradingstrategy.ai","new_version_id":"enzyme-polygon-eth-btc-rsi","frontpage":true},{"id":"enzyme-polygon-matic-usdc","name":"MATIC breakout","url":"https://enzyme-polygon-matic-usdc.tradingstrategy.ai"},{"id":"enzyme-polygon-eth-breakout","name":"ETH breakout","url":"https://enzyme-polygon-eth-breakout.tradingstrategy.ai"},{"id":"enzyme-polygon-eth-usdc","name":"ETH Breakout bounce","url":"https://enzyme-polygon-eth-usdc.tradingstrategy.ai"},{"id":"enzyme-polygon-eth-usdc-sls","name":"ETH Balance snap","url":"https://enzyme-polygon-eth-usdc-sls.tradingstrategy.ai"},{"id":"polygon-eth-spot-short","name":"ETH mean reversion bounce","url":"https://polygon-eth-spot-short.tradingstrategy.ai"},{"id":"arbitrum-btc-breakout","name":"BTC Barrier Breach","url":"https://arbitrum-btc-breakout.tradingstrategy.ai"}]' +TS_PUBLIC_STRATEGIES='[{"id":"enzyme-polygon-matic-eth-usdc","name":"ETH-MATIC-USDC momentum","url":"https://enzyme-polygon-matic-eth-usdc.tradingstrategy.ai","frontpage":true},{"id":"enzyme-arbitrum-eth-btc-rsi","name":"ETH-BTC price surge (Arbitrum)","url":"https://enzyme-arbitrum-eth-btc-rsi.tradingstrategy.ai/","frontpage":true},{"id":"enzyme-polygon-eth-rolling-ratio","name":"ETH/BTC rolling ratio","url":"https://enzyme-polygon-eth-rolling-ratio.tradingstrategy.ai/","frontpage":true},{"id":"enzyme-polygon-eth-btc-rsi","name":"ETH-BTC price surge","url":"https://enzyme-polygon-eth-btc-rsi.tradingstrategy.ai/","frontpage":true,"hiddenPositions":[4]},{"id":"enzyme-ethereum-btc-eth-stoch-rsi","name":"Stochastic ETH/BTC long","url":"https://enzyme-ethereum-btc-eth-stoch-rsi.tradingstrategy.ai","frontpage":true},{"id":"enzyme-polygon-eth-btc-usdc","name":"ETH-BTC-USDC momentum","url":"https://enzyme-polygon-eth-btc-usdc.tradingstrategy.ai","new_version_id":"enzyme-polygon-eth-btc-rsi","frontpage":true},{"id":"enzyme-polygon-matic-usdc","name":"MATIC breakout","url":"https://enzyme-polygon-matic-usdc.tradingstrategy.ai"},{"id":"enzyme-polygon-eth-breakout","name":"ETH breakout","url":"https://enzyme-polygon-eth-breakout.tradingstrategy.ai"},{"id":"enzyme-polygon-eth-usdc","name":"ETH Breakout bounce","url":"https://enzyme-polygon-eth-usdc.tradingstrategy.ai"},{"id":"enzyme-polygon-eth-usdc-sls","name":"ETH Balance snap","url":"https://enzyme-polygon-eth-usdc-sls.tradingstrategy.ai"},{"id":"polygon-eth-spot-short","name":"ETH mean reversion bounce","url":"https://polygon-eth-spot-short.tradingstrategy.ai"},{"id":"arbitrum-btc-breakout","name":"BTC Barrier Breach","url":"https://arbitrum-btc-breakout.tradingstrategy.ai"}]' TS_PUBLIC_GEO_BLOCK='{"strategies:view":["CU","IR","KP","RU","SY"],"strategies:deposit":["CU","IR","KP","RU","SY","US","UK"]}' # Uncomment to test chain maintenance error # TS_PUBLIC_CHAINS_UNDER_MAINTENANCE='{ "binance": "BNB Chain" }' diff --git a/src/lib/assets/logos/tokens/pol.svg b/src/lib/assets/logos/tokens/pol.svg new file mode 100644 index 000000000..1b1c21744 --- /dev/null +++ b/src/lib/assets/logos/tokens/pol.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/lib/assets/logos/tokens/usdt.svg b/src/lib/assets/logos/tokens/usdt.svg new file mode 100644 index 000000000..38c491c99 --- /dev/null +++ b/src/lib/assets/logos/tokens/usdt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/lib/assets/tos/tos-map.json b/src/lib/assets/tos/tos-map.json deleted file mode 100644 index e6dc9ca17..000000000 --- a/src/lib/assets/tos/tos-map.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "1": { - "0xd63c1bE9D8B56CCcD6fd2Dd9F9c030c6a9916f5F": { - "1": { - "fileName": "2024-03-20.txt", - "acceptanceMessage": "I agree on Terms of Service. I understand smart contract trading is risky and I may lose all of my deposits. \n\nThis Terms of Service version 1, dated 2024-03-20, was published at https://tradingstrategy.ai/tos/2024-03-20.txt" - } - } - }, - - "137": { - "0xbe1418df0bAd87577de1A41385F19c6e77312780": { - "1": { - "fileName": "155d6737cb.txt", - "acceptanceMessage": "I read and agree on terms of service (version 1) to use\nsmart contract software deployed on a blockchain. \n\nThe terms of service text was published 10.1.2024 at https://example.com.\nThe unique identifier hash for this terms of service text was 0x0000000000000000000000000000000000000000." - }, - "2": { - "fileName": "2024-03-20.txt", - "acceptanceMessage": "I read and agree on Terms of Service to access the\\nsmart contract software deployed on a blockchain.\\n\\nThe Terms of Service version 2, dated 2024-03-20, was published at \\nhttps://tradingstrategy.ai/tos/2024-03-20.txt" - }, - "3": { - "fileName": "2024-03-20.txt", - "acceptanceMessage": "I read and agree on Terms of Service to access the\nsmart contract software deployed on a blockchain.\n\nThe Terms of Service version 3, dated 2024-03-20, was published at \nhttps://tradingstrategy.ai/tos/2024-03-20.txt" - }, - "4": { - "fileName": "2024-03-30.txt", - "acceptanceMessage": "" - }, - "5": { - "fileName": "2024-03-30.txt", - "acceptanceMessage": "I agree on Terms of Service. I understand smart contract trading is risky and I may lose all of my deposits. \n\nThis Terms of Service version 5, dated 2024-03-30, was published at https://tradingstrategy.ai/tos/2024-03-30.txt" - } - }, - "0x24BB78E70bE0fC8e93Ce90cc8A586e48428Ff515": { - "2": { - "fileName": "155d6737cb.txt", - "acceptanceMessage": "Hello world" - } - } - } -} diff --git a/src/lib/eth-defi/helpers.ts b/src/lib/eth-defi/helpers.ts index 3b83afe98..8619f8435 100644 --- a/src/lib/eth-defi/helpers.ts +++ b/src/lib/eth-defi/helpers.ts @@ -1,10 +1,9 @@ import type { Abi, Log } from 'viem'; import type { Config, GetBalanceParameters, GetBalanceReturnType } from '@wagmi/core'; import { decodeEventLog, formatUnits, isAddressEqual, parseAbi, erc20Abi } from 'viem'; -import { readContract, readContracts } from '@wagmi/core'; +import { readContract, readContracts, simulateContract, writeContract } from '@wagmi/core'; import comptrollerABI from '$lib/eth-defi/abi/enzyme/ComptrollerLib.json'; import { formatNumber } from '$lib/helpers/formatters'; -import tosMap from '$lib/assets/tos/tos-map.json'; /** * Extract events from transaction logs @@ -119,38 +118,60 @@ export function getTokenLabel(symbol: string | undefined, address: Address) { } /** - * Get a strategy denomination token balance for a given comptroller and address + * Get a strategy denomination token address for a given chain and comptroller */ -export async function getDenominationToken( +export async function getDenominationAsset( config: Config, - { comptroller, address, chainId }: { comptroller: Address; address: Address; chainId?: number | undefined } + { chainId, comptroller }: { chainId?: number; comptroller: Address } ) { - const token = (await readContract(config, { + return readContract(config, { chainId, address: comptroller, abi: comptrollerABI, functionName: 'getDenominationAsset' - })) as Address; - - return getTokenBalance(config, { address, token, chainId }); + }) as Promise
; } -export type TosInfo = { - fileName?: string; - acceptanceMessage?: string; -}; +/** + * Get strategy denomination token info for a given chain and comptroller + */ +export async function getDenominationTokenInfo( + config: Config, + { chainId, comptroller }: { chainId?: number; comptroller: Address } +) { + const address = await getDenominationAsset(config, { chainId, comptroller }); + return getTokenInfo(config, { chainId, address }); +} /** - * Get Terms of Service info based on the mapping stored in: src/lib/assets/tos/tos-map.json - * - * The mapping is stored in the form: chainId -> address -> version -> TosInfo - * - * @param chainId - chainId of the strategy - * @param address - Terms of Service contract address of the strategy - * @param version - Terms of Service version - * + * Get strategy denomination token balance for a given chain, comptroller and address */ -export function getTosInfo(chainId: number, address: string, version: number): TosInfo { - // @ts-ignore - return tosMap[chainId]?.[address]?.[version] ?? {}; +export async function getDenominationTokenBalance( + config: Config, + { chainId, comptroller, address }: { chainId?: number; comptroller: Address; address: Address } +) { + const token = await getDenominationAsset(config, { chainId, comptroller }); + return getTokenBalance(config, { chainId, token, address }); +} + +type ApproveTokenTransferParams = { + chainId?: number; + address: Address; + sender: Address; + value: number | bigint; +}; + +export async function approveTokenTransfer( + config: Config, + { chainId, address, sender, value }: ApproveTokenTransferParams +) { + const { request } = await simulateContract(config, { + abi: erc20Abi, + chainId, + address, + functionName: 'approve', + args: [sender, BigInt(value)] + }); + + return writeContract(config, request); } diff --git a/src/lib/trade-executor/helpers/tos.ts b/src/lib/trade-executor/helpers/tos.ts new file mode 100644 index 000000000..d839711c3 --- /dev/null +++ b/src/lib/trade-executor/helpers/tos.ts @@ -0,0 +1,96 @@ +/** + * This module is used to map Terms of Service contracts and versions for each blockchain + * to corresponding ToS file versions and acceptance messages. + * + * The acceptance message is needed to generate a hash and signature; we currently don't + * have a way to retrieve this directly from the blockchain, so it is made available via + * this local mapping. + */ +export type TosVersionParams = { + chainId: number; + address: Address; + version: number; +}; + +export type TosVersion = TosVersionParams & { + fileName?: string; + acceptanceMessage?: string; +}; + +const tosVersions: TosVersion[] = [ + // Etherium versions + { + chainId: 1, + address: '0xd63c1bE9D8B56CCcD6fd2Dd9F9c030c6a9916f5F', + version: 1, + fileName: '2024-03-20.txt', + acceptanceMessage: + 'I agree on Terms of Service. I understand smart contract trading is risky and I may lose all of my deposits. \n\nThis Terms of Service version 1, dated 2024-03-20, was published at https://tradingstrategy.ai/tos/2024-03-20.txt' + }, + + // Polygon versions + { + chainId: 137, + address: '0xbe1418df0bAd87577de1A41385F19c6e77312780', + version: 1, + fileName: '155d6737cb.txt', + acceptanceMessage: + 'I read and agree on terms of service (version 1) to use\nsmart contract software deployed on a blockchain. \n\nThe terms of service text was published 10.1.2024 at https://example.com.\nThe unique identifier hash for this terms of service text was 0x0000000000000000000000000000000000000000.' + }, + { + chainId: 137, + address: '0xbe1418df0bAd87577de1A41385F19c6e77312780', + version: 2, + fileName: '2024-03-20.txt', + acceptanceMessage: + 'I read and agree on Terms of Service to access the\\nsmart contract software deployed on a blockchain.\\n\\nThe Terms of Service version 2, dated 2024-03-20, was published at \\nhttps://tradingstrategy.ai/tos/2024-03-20.txt' + }, + { + chainId: 137, + address: '0xbe1418df0bAd87577de1A41385F19c6e77312780', + version: 3, + fileName: '2024-03-20.txt', + acceptanceMessage: + 'I read and agree on Terms of Service to access the\nsmart contract software deployed on a blockchain.\n\nThe Terms of Service version 3, dated 2024-03-20, was published at \nhttps://tradingstrategy.ai/tos/2024-03-20.txt' + }, + { + chainId: 137, + address: '0xbe1418df0bAd87577de1A41385F19c6e77312780', + version: 4, + fileName: '2024-03-30.txt', + acceptanceMessage: '' + }, + { + chainId: 137, + address: '0xbe1418df0bAd87577de1A41385F19c6e77312780', + version: 5, + fileName: '2024-03-30.txt', + acceptanceMessage: + 'I agree on Terms of Service. I understand smart contract trading is risky and I may lose all of my deposits. \n\nThis Terms of Service version 5, dated 2024-03-30, was published at https://tradingstrategy.ai/tos/2024-03-30.txt' + }, + + // Arbitrum versions + { + chainId: 42161, + address: '0xDCD7C644a6AA72eb2f86781175b18ADc30Aa4f4d', + version: 1, + fileName: '2024-03-20.txt', + acceptanceMessage: + 'I agree on Terms of Service. I understand smart contract trading is risky and I may lose all of my deposits. \n\nThis Terms of Service version 1, dated 2024-03-20, was published at https://tradingstrategy.ai/tos/2024-03-20.txt' + } +]; + +/** + * Get Terms of Service version info for a given chain, address and version + * + * @param chainId - chainId of the strategy + * @param address - Terms of Service contract address of the strategy + * @param version - Terms of Service version + * + */ +export function getTosVersion(params: TosVersionParams): TosVersion { + const tosVersion = tosVersions.find((tos) => { + return (['chainId', 'address', 'version'] as const).every((key) => tos[key] === params[key]); + }); + return { ...params, ...tosVersion }; +} diff --git a/src/lib/trade-executor/strategy/summary.ts b/src/lib/trade-executor/strategy/summary.ts index ab86e1e3b..b9e05454d 100644 --- a/src/lib/trade-executor/strategy/summary.ts +++ b/src/lib/trade-executor/strategy/summary.ts @@ -24,15 +24,10 @@ import { keyMetricSchema } from '../statistics/key-metric'; export const assetManagementMode = z.enum(['hot_wallet', 'enzyme']); export const enzymeSmartContractsSchema = z.object({ - vault: hexString.nullish(), - comptroller: hexString.nullish(), - generic_adapter: hexString.nullish(), - gas_relay_paymaster_lib: hexString.nullish(), - gas_relay_paymaster_factory: hexString.nullish(), - integration_manager: hexString.nullish(), - fund_value_calculator: hexString.nullish(), - payment_forwarder: hexString.nullish(), - guard: hexString.nullish(), + vault: hexString, + comptroller: hexString, + fund_value_calculator: hexString, + payment_forwarder: hexString, terms_of_service: hexString.nullish() }); export type EnzymeSmartContracts = z.infer; @@ -40,7 +35,7 @@ export type EnzymeSmartContracts = z.infer; export const onChainDataSchema = z.object({ chain_id: chainId.nullish(), asset_management_mode: assetManagementMode, - smart_contracts: enzymeSmartContractsSchema, + smart_contracts: enzymeSmartContractsSchema.partial(), owner: hexString.nullish(), trade_executor_hot_wallet: hexString.nullish() }); diff --git a/src/lib/wallet/VaultBalance.svelte b/src/lib/wallet/VaultBalance.svelte index 1033103ad..c5ed6aaec 100644 --- a/src/lib/wallet/VaultBalance.svelte +++ b/src/lib/wallet/VaultBalance.svelte @@ -18,7 +18,7 @@ const value = fetchVaultNetValue(address); async function fetchVaultShares(address: Address) { - const vaultShares = await getTokenBalance(config, { token: contracts.vault!, address }); + const vaultShares = await getTokenBalance(config, { token: contracts.vault, address }); dispatch('dataFetch', { vaultShares }); return vaultShares; } diff --git a/src/routes/wizard/connect-wallet/balance/+page.ts b/src/routes/wizard/connect-wallet/balance/+page.ts index cf6115c9d..223250a40 100644 --- a/src/routes/wizard/connect-wallet/balance/+page.ts +++ b/src/routes/wizard/connect-wallet/balance/+page.ts @@ -3,16 +3,19 @@ import { get } from 'svelte/store'; import { wizard } from 'wizard/store'; import { type ConfiguredChainId, config } from '$lib/wallet'; import { getAccount, getBalance } from '@wagmi/core'; -import { type GetTokenBalanceReturnType, getDenominationToken } from '$lib/eth-defi/helpers'; +import { type GetTokenBalanceReturnType, getDenominationTokenBalance } from '$lib/eth-defi/helpers'; export async function load() { const { address } = getAccount(config) as { address: Address }; - const { chainId, contracts } = get(wizard).data! as { chainId: ConfiguredChainId; contracts: EnzymeSmartContracts }; + const { chainId, contracts } = get(wizard).data! as { + chainId: ConfiguredChainId; + contracts: Partial; + }; const { comptroller } = contracts; let denominationToken: Promise | undefined = undefined; if (comptroller) { - denominationToken = getDenominationToken(config, { address, comptroller, chainId }); + denominationToken = getDenominationTokenBalance(config, { address, comptroller, chainId }); } return { diff --git a/src/routes/wizard/deposit/+layout.ts b/src/routes/wizard/deposit/+layout.ts index 845d90ed5..767e7cb8e 100644 --- a/src/routes/wizard/deposit/+layout.ts +++ b/src/routes/wizard/deposit/+layout.ts @@ -1,7 +1,21 @@ import type { EnzymeSmartContracts } from 'trade-executor/strategy/summary'; +import { type ConfiguredChainId, config } from '$lib/wallet'; import { get } from 'svelte/store'; import { wizard } from 'wizard/store'; import { assertNotGeoBlocked } from '$lib/helpers/geo'; +import { type TokenInfo, type GetTokenBalanceReturnType, getDenominationTokenInfo } from '$lib/eth-defi/helpers'; + +export type DepositWizardData = { + chainId: ConfiguredChainId; + strategyName: string; + contracts: EnzymeSmartContracts; + canForwardPayment: boolean; + denominationTokenInfo: TokenInfo; + denominationToken?: GetTokenBalanceReturnType; + nativeCurrency?: GetTokenBalanceReturnType; + tosSignature?: Address | ''; + tosHash?: Address; +}; export async function load({ parent }) { const { admin, ipCountry } = await parent(); @@ -18,11 +32,21 @@ export async function load({ parent }) { { slug: 'success', label: 'Success' } ]; + const { chainId, contracts } = get(wizard).data as DepositWizardData; + const { comptroller, terms_of_service } = contracts; + // skip "Terms of service" step if no terms_of_service contract - const contracts: EnzymeSmartContracts = get(wizard).data!.contracts; - if (!contracts.terms_of_service) { + if (!terms_of_service) { steps = steps.filter(({ slug }) => slug !== 'tos'); } + // get denomination token info + const denominationTokenInfo = await getDenominationTokenInfo(config, { chainId, comptroller }); + + // USDC can forward payment using transferWithAuthorizations; other tokens can't (yet) + const canForwardPayment = denominationTokenInfo.symbol === 'USDC'; + + wizard.updateData({ denominationTokenInfo, canForwardPayment }); + return { title, steps }; } diff --git a/src/routes/wizard/deposit/balance/+page.ts b/src/routes/wizard/deposit/balance/+page.ts index 080e0be01..da7f360ff 100644 --- a/src/routes/wizard/deposit/balance/+page.ts +++ b/src/routes/wizard/deposit/balance/+page.ts @@ -1,18 +1,18 @@ -import type { EnzymeSmartContracts } from 'trade-executor/strategy/summary'; +import type { DepositWizardData } from '../+layout'; import { get } from 'svelte/store'; import { wizard } from 'wizard/store'; -import { type ConfiguredChainId, config } from '$lib/wallet'; +import { config } from '$lib/wallet'; import { getAccount, getBalance } from '@wagmi/core'; -import { getDenominationToken } from '$lib/eth-defi/helpers'; +import { getDenominationTokenBalance } from '$lib/eth-defi/helpers'; export async function load() { const { address } = getAccount(config) as { address: Address }; - const { chainId, contracts } = get(wizard).data! as { chainId: ConfiguredChainId; contracts: EnzymeSmartContracts }; - const comptroller = contracts.comptroller!; + const { chainId, contracts } = get(wizard).data as DepositWizardData; + const { comptroller } = contracts; return { chainId, nativeCurrency: await getBalance(config, { address, chainId }), - denominationToken: await getDenominationToken(config, { address, comptroller, chainId }) + denominationToken: await getDenominationTokenBalance(config, { address, comptroller, chainId }) }; } diff --git a/src/routes/wizard/deposit/connect/+page.svelte b/src/routes/wizard/deposit/connect/+page.svelte index 1188c4951..657c4f60d 100644 --- a/src/routes/wizard/deposit/connect/+page.svelte +++ b/src/routes/wizard/deposit/connect/+page.svelte @@ -1,8 +1,9 @@ diff --git a/src/routes/wizard/deposit/introduction/+page.svelte b/src/routes/wizard/deposit/introduction/+page.svelte index 1579637a7..f2b30c0e0 100644 --- a/src/routes/wizard/deposit/introduction/+page.svelte +++ b/src/routes/wizard/deposit/introduction/+page.svelte @@ -1,13 +1,16 @@

- Ready to deposit in {$wizard.data.strategyName}? Deposit USDC.e to add this strategy to your DeFi - trading portfolio. Connect your wallet, review your balances, enter your desired deposit amount, and make your - payment. Let's get started! + Ready to deposit in {strategyName}? Deposit {denominationTokenInfo.label} to add this + strategy to your DeFi trading portfolio. Connect your wallet, review your balances, enter your desired deposit amount, + and make your payment. Let's get started!

diff --git a/src/routes/wizard/deposit/payment/+page.svelte b/src/routes/wizard/deposit/payment/+page.svelte index 4af22c7c8..a69b53760 100644 --- a/src/routes/wizard/deposit/payment/+page.svelte +++ b/src/routes/wizard/deposit/payment/+page.svelte @@ -1,20 +1,16 @@
@@ -301,7 +377,7 @@ -
+ wizard.updateData({ paymentValue })} > Estimated shares: {getEstimatedShares(paymentValue, sharePrice)} - {#if $payment === 'initial'} - + {#if !['processing', 'completed'].includes($payment)} + {#if canForwardPayment} + + {:else} +
+ + +
+ {/if} + {:else if paymentTxId} +
+

Transaction ID

+ +
+ {/if} - - + {#if $progressBar >= 0} + {/if} {#if $payment === 'authorizing'} - + Authorise the EIP-3009 transfer of {denominationToken.symbol} tokens from your wallet. If your wallet does not support the EIP-3009 transfer type, you will be prompted to sign a message and then send a transaction. {/if} - {#if $payment === 'confirming'} - - Please confirm the transaction in your wallet in order submit your payment. + {#if $payment === 'approving'} + + Please approve the requested {denominationToken.label} spending cap in your wallet. This allows the designated + amount of {denominationToken.label} to be transfered from your wallet to purchase shares. {/if} - {#if transactionId} -
-

Transaction ID

- -
+ {#if $payment === 'approved'} + + {denominationToken.label} spending cap approved. Please click "Buy shares" to complete your purchase. + + {/if} - + {#if $payment === 'processingApproval'} + + The duration of processing may vary based on factors such as blockchain congestion and gas specified. + {viewTransactionCopy} + + {/if} + + {#if $payment === 'confirming'} + + Please confirm the transaction in your wallet in order submit your payment. + {/if} {#if $payment === 'processing'} @@ -410,6 +508,12 @@ gap: var(--space-xl); } + .buttons { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); + gap: 0.75rem; + } + progress { width: 100%; } diff --git a/src/routes/wizard/deposit/payment/+page.ts b/src/routes/wizard/deposit/payment/+page.ts index 2ffa53008..707f4349f 100644 --- a/src/routes/wizard/deposit/payment/+page.ts +++ b/src/routes/wizard/deposit/payment/+page.ts @@ -1,9 +1,10 @@ -import type { Abi } from 'viem'; -import type { EnzymeSmartContracts } from 'trade-executor/strategy/summary'; +import type { Abi, ContractFunctionParameters } from 'viem'; +import type { DepositWizardData } from '../+layout'; import { get } from 'svelte/store'; import { wizard } from 'wizard/store'; import { readContract } from '@wagmi/core'; import { config } from '$lib/wallet'; +import comptrollerABI from '$lib/eth-defi/abi/enzyme/ComptrollerLib.json'; import paymentForwarderABI from '$lib/eth-defi/abi/VaultUSDCPaymentForwarder.json'; import termsPaymentForwarderABI from '$lib/eth-defi/abi/TermedVaultUSDCPaymentForwarder.json'; @@ -23,22 +24,33 @@ async function paymentForwarderRequiresTos(address: Address) { } export async function load() { - const contracts = get(wizard).data!.contracts as EnzymeSmartContracts; - const address = contracts.payment_forwarder!; + const { canForwardPayment, contracts } = get(wizard).data as DepositWizardData; + const { comptroller, payment_forwarder } = contracts; - const tosRequired = await paymentForwarderRequiresTos(address); + let paymentContract: ContractFunctionParameters; + let tosRequired = false; - const paymentContract = tosRequired - ? { - address, - abi: termsPaymentForwarderABI as Abi, - functionName: 'buySharesOnBehalfUsingTransferWithAuthorizationAndTermsOfService' - } - : { - address, - abi: paymentForwarderABI as Abi, - functionName: 'buySharesOnBehalfUsingTransferWithAuthorization' - }; + if (!canForwardPayment) { + paymentContract = { + address: comptroller, + abi: comptrollerABI as Abi, + functionName: 'buySharesOnBehalf' + }; + } else { + tosRequired = await paymentForwarderRequiresTos(payment_forwarder); + + paymentContract = tosRequired + ? { + address: payment_forwarder, + abi: termsPaymentForwarderABI as Abi, + functionName: 'buySharesOnBehalfUsingTransferWithAuthorizationAndTermsOfService' + } + : { + address: payment_forwarder, + abi: paymentForwarderABI as Abi, + functionName: 'buySharesOnBehalfUsingTransferWithAuthorization' + }; + } return { paymentContract, tosRequired }; } diff --git a/src/routes/wizard/deposit/success/+page.svelte b/src/routes/wizard/deposit/success/+page.svelte index e046fca4a..c0266300d 100644 --- a/src/routes/wizard/deposit/success/+page.svelte +++ b/src/routes/wizard/deposit/success/+page.svelte @@ -1,9 +1,11 @@ diff --git a/src/routes/wizard/deposit/tos/+page.svelte b/src/routes/wizard/deposit/tos/+page.svelte index 9f597a713..01deba0b2 100644 --- a/src/routes/wizard/deposit/tos/+page.svelte +++ b/src/routes/wizard/deposit/tos/+page.svelte @@ -1,31 +1,58 @@ @@ -131,32 +218,60 @@ + {#if ['initial', 'valid', 'ready'].includes($tos)} + +