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}
+ />
+
+
+
+
+ )
+}