diff --git a/app/components/Effect.tsx b/app/components/Effect.tsx index f7489cf8c..1b5777c41 100644 --- a/app/components/Effect.tsx +++ b/app/components/Effect.tsx @@ -12,6 +12,7 @@ import RelativeTime from "./shared/RelativeTime" import TransactionHash from "./shared/TransactionHash" import { base64Decode } from "../lib/utils" +import Unrecognized from "./operations/Unrecognized" export type EffectProps = ServerApi.EffectRecord & { op?: ServerApi.OperationRecord } @@ -209,6 +210,63 @@ const Thresholds = ({ lowThreshold, medThreshold, highThreshold }: any) => ( ) +const ClaimableBalanceCreated = ({ account, amount, asset }: any) => { + const [assetCode, assetIssuer] = asset.split(':') + return ( + + created balance for {amount} + ) +} + +const ClaimableBalanceClaimed = ({ account, amount, asset }: any) => { + const [assetCode, assetIssuer] = asset.split(':') + return ( + + claimed {amount} + ) +} + +const ClaimableBalanceClaimantCreated = ({ account, amount, asset, predicate }: any) => { + const [assetCode, assetIssuer] = asset.split(':') + return ( + + sponsored for {amount} + ) +} + +const ClaimableBalanceSponsorshipCreated = ({ sponsor }: any) => ( + + created claimable balance sponsorship + +) + +const ClaimableBalanceSponsorshipRemoved = ({ account, formerSponsor }: any) => ( + + revoked sponsored balance from + +) + +const LiquidityPoolTrade = ({ account, bought, sold }: any) => { + const [boughtCode, boughtIssuer] = bought.asset.split(':') + const [soldCode, soldIssuer] = sold.asset.split(':') + + return ( + + bought {bought.amount}  + for  + {sold.amount}  + + + ) +} + +const Fallback = (props: any) => ( + + Not handled, keys are: + {Object.keys(props).join(',')} + +) + const effectTypeComponentMap = { account_created: AccountCreated, account_removed: AccountRemoved, @@ -235,6 +293,32 @@ const effectTypeComponentMap = { data_updated: Data, contract_credited: ContractDebitCredit, contract_debited: ContractDebitCredit, + + claimable_balance_created: ClaimableBalanceCreated, + claimable_balance_claimed: ClaimableBalanceClaimed, + claimable_balance_claimant_created: ClaimableBalanceClaimantCreated, + // account_sponsorship_created + // account_sponsorship_updated + // account_sponsorship_removed + // trustline_sponsorship_created + // trustline_sponsorship_updated + // trustline_sponsorship_removed + // data_sponsorship_created + // data_sponsorship_updated + // data_sponsorship_removed + claimable_balance_sponsorship_created: ClaimableBalanceSponsorshipCreated, + // claimable_balance_sponsorship_updated + claimable_balance_sponsorship_removed: ClaimableBalanceSponsorshipRemoved, + // signer_sponsorship_created + // signer_sponsorship_updated + // signer_sponsorship_removed + + // - liquidity_pool_deposited + // - liquidity_pool_withdrew + liquidity_pool_trade: LiquidityPoolTrade, + // - liquidity_pool_created + // - liquidity_pool_removed + // - liquidity_pool_revoked } type EffectComponentMapKey = keyof typeof effectTypeComponentMap diff --git a/app/components/operations/ClaimableBalances.tsx b/app/components/operations/ClaimableBalances.tsx new file mode 100644 index 000000000..cd9ef8838 --- /dev/null +++ b/app/components/operations/ClaimableBalances.tsx @@ -0,0 +1,12 @@ +import AccountLink from "../shared/AccountLink" +import Asset from "../shared/Asset" + +const CreateClaimableBalanceOperation = ({ amount, sponsor, asset }: any) => { + const [assetCode, assetIssuer] = asset.split(':') + return ( + + created claimable balance for {amount} + ) +} + +export { CreateClaimableBalanceOperation } \ No newline at end of file diff --git a/app/components/operations/LiquidityPool.tsx b/app/components/operations/LiquidityPool.tsx new file mode 100644 index 000000000..4c6f8c5a0 --- /dev/null +++ b/app/components/operations/LiquidityPool.tsx @@ -0,0 +1,6 @@ +import AccountLink from "../shared/AccountLink" +import Asset from "../shared/Asset" + + + +// export { LiquidityPoolTradeOperation } \ No newline at end of file diff --git a/app/components/operations/Operation.tsx b/app/components/operations/Operation.tsx index 90d1273ba..164904d6d 100644 --- a/app/components/operations/Operation.tsx +++ b/app/components/operations/Operation.tsx @@ -10,6 +10,7 @@ import AccountMerge from "./AccountMerge" import AllowTrust, { AllowTrustProps } from "./AllowTrust" import BumpSequence from "./BumpSequence" import ChangeTrust from "./ChangeTrust" +import { CreateClaimableBalanceOperation } from "./ClaimableBalances" import CreateAccount, { CreateAccountProps } from "./CreateAccount" import Inflation from "./Inflation" import InvokeHostFunction from "./InvokeHostFunction" @@ -30,6 +31,8 @@ const OperationTypeToComponentMap = { create_passive_sell_offer: Offer, create_passive_offer: Offer, // < Protocol 11 + create_claimable_balance: CreateClaimableBalanceOperation, + inflation: Inflation, invoke_host_function: InvokeHostFunction, diff --git a/app/components/operations/Unrecognized.tsx b/app/components/operations/Unrecognized.tsx index e32d7e391..a5d0b2b9e 100644 --- a/app/components/operations/Unrecognized.tsx +++ b/app/components/operations/Unrecognized.tsx @@ -1,10 +1,14 @@ import { FormattedMessage } from 'react-intl' -const Unrecognized = ({ type }: { type: string }) => +const Unrecognized = (props: any) => { + const { type }: { type: string } = props + console.log(JSON.stringify(props, null, 2)) + return () +} export default Unrecognized diff --git a/app/components/shared/Asset.tsx b/app/components/shared/Asset.tsx index 4385c49c0..e37eb6c19 100644 --- a/app/components/shared/Asset.tsx +++ b/app/components/shared/Asset.tsx @@ -8,7 +8,7 @@ interface AssetProps { } export default ({ code, issuer, type }: AssetProps) => { - const isLumens = type === 'native' + const isLumens = type === 'native' || code === 'native' const propCode = isLumens ? 'XLM' : code return ( diff --git a/app/lib/stellar/xdr_scval_utils.ts b/app/lib/stellar/xdr_scval_utils.ts index b077cd211..1527e213e 100644 --- a/app/lib/stellar/xdr_scval_utils.ts +++ b/app/lib/stellar/xdr_scval_utils.ts @@ -22,6 +22,8 @@ export const scValToString = (scVal: any) => { return native } else if (typeof native === 'bigint') { return native.toString() + } else if (Array.isArray(native)) { + return native.map(val => typeof val === 'bigint' ? val.toString() : val) } else { return JSON.stringify(native) } diff --git a/app/routes/effects.$opId.tsx b/app/routes/effects.$opId.tsx new file mode 100644 index 000000000..66cb39abf --- /dev/null +++ b/app/routes/effects.$opId.tsx @@ -0,0 +1,60 @@ +import type { ServerApi } from "stellar-sdk" + +import Card from 'react-bootstrap/Card' +import CardHeader from 'react-bootstrap/CardHeader' +import Container from 'react-bootstrap/Container' +import Row from 'react-bootstrap/Row' +import { FormattedMessage, useIntl } from 'react-intl' +import { requestToServer } from '~/lib/stellar/server' + +import { LoaderArgs, json } from '@remix-run/node' +import { useLoaderData } from '@remix-run/react' + +import EffectTable from '../components/EffectTable' +import { setTitle } from '../lib/utils' + +import { effects } from '~/lib/stellar/server_request_utils' +import { EffectProps } from "~/components/Effect" +import { useEffect } from "react" + +export const loader = ({ request, params }: LoaderArgs) => { + const server = requestToServer(request) + return effects(server, { operationId: params.opId }).then(effects => + effects.map( + (effect: ServerApi.EffectRecord) => ({ + ...effect, + op: effect.operation ? effect.operation() : undefined + }) as EffectProps + ) + ).then(json) +} + +export default function Effects() { + const records = useLoaderData() + + const { formatMessage } = useIntl() + useEffect(() => { + setTitle(formatMessage({ id: 'effects' })) + }, []) + + return ( + + + + + + + + } + // showEffect + // showSource + // compact={false} + // limit={20} + /> + + + + + ) +}