Skip to content

Commit

Permalink
add Storage tab to contracts
Browse files Browse the repository at this point in the history
make use of scValToNative
  • Loading branch information
chatch committed Sep 15, 2023
1 parent 54802ba commit f6f6c2c
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 71 deletions.
2 changes: 2 additions & 0 deletions api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ const decompileLimiter = rateLimit({

const app = express();

app.set('trust proxy', 2)

/**
* Decompile a wasm file using the wabt wasm-decompile tool
*
Expand Down
45 changes: 4 additions & 41 deletions app/components/operations/InvokeHostFunction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,19 @@ import truncate from 'lodash/truncate'

import { xdr } from '../../lib/stellar'
import {
scValToAddress,
scValToAddress, scValToString,
} from '../../lib/stellar/xdr_scval_utils'
import { scValToNative } from 'soroban-client'
import AccountLink from '../shared/AccountLink'

type HostFunctionParams = any // TODO: restore this after seeing live data: ReadonlyArray<Record<'key' | 'value' | 'type', string>>

const scValToString = (type: string, scVal: any) => {
let str
switch (type) {
case 'Bytes':
str = scVal.bytes().toString('hex')
break
case 'Str':
str = scVal.str().toString()
break
case 'Address':
str = scValToAddress(scVal)
break
case 'Sym':
str = scVal.sym().toString()
break
case 'U32':
case 'I32':
case 'U64':
case 'I64':
case 'U128':
case 'I128':
case 'I256':
str = String(scValToNative(scVal))
break
case '':
case 'Void': // not seeing this yet but assuming it will be changed from '' to 'Void' at some point
str = ''
break
// TODO: #513
// case 'Map':
// const map = scVal.map()
// str = JSON.stringify(map)
// break
default:
str = undefined
}
return str
}


const invokeFunctionParamsRawtoRendered = (params: HostFunctionParams) =>
params.map((p: any) => {
let scVal = xdr.ScVal.fromXDR(p.value, 'base64')
let renderStr = scValToString(p.type, scVal) || p.value
let renderStr = scValToString(scVal) || p.value
return { key: p.type || 'Void', value: renderStr }
})

Expand All @@ -61,7 +24,7 @@ const renderContractParams = (
params: any
) =>
params.map(({ key, value }: { key: string, value: string }, idx: number) => (
<span key={idx}>&nbsp;&nbsp;&nbsp;&nbsp;
<span key={idx} className="invoke-param">
<span title={value}>{
key === 'Address' ?
<AccountLink account={value} /> :
Expand Down
23 changes: 21 additions & 2 deletions app/lib/stellar/contracts.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Contract } from 'soroban-client'
import { SorobanServer, xdr } from '../stellar'
import { hexStringToBytes } from '../utils'
import { scValToString } from './xdr_scval_utils'

const API_URL = `https://steexp-api.fly.dev`
// const API_URL = `http://localhost:3001`
Expand All @@ -13,6 +14,22 @@ interface ContractProps {
wasmCodeLedger: string
}

interface StorageElement {
key: string
keyType: string
value: string
valueType: string
}

const convertStorage = (
storage: ReadonlyArray<xdr.ScMapEntry>
): ReadonlyArray<StorageElement> => storage.map(el => ({
key: scValToString(el.key()),
keyType: el.key().switch().name,
value: scValToString(el.val()),
valueType: el.val().switch().name,
}))

const getContractInfo = async (
server: SorobanServer,
contractId: string
Expand All @@ -39,7 +56,9 @@ const getContractInfo = async (

const contractInstance = codeData.val().instance()
const wasmId = contractInstance.executable().wasmHash()
const storage = contractInstance.storage()

const contractStorage = contractInstance.storage()
const storage = contractStorage ? convertStorage(contractStorage) : []

return { wasmId, wasmIdLedger, storage }
}
Expand Down Expand Up @@ -132,7 +151,7 @@ const postWasmToWabtBackendRoute = (
const getContractDecompiled = postWasmToWabtBackendRoute(`/decompile`)
const getContractWat = postWasmToWabtBackendRoute(`/wat`)

export type { ContractProps }
export type { ContractProps, StorageElement }

export {
getContractCode,
Expand Down
15 changes: 14 additions & 1 deletion app/lib/stellar/xdr_scval_utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { StrKey, xdr } from 'soroban-client'
import { StrKey, scValToNative, xdr } from 'soroban-client'

export function scValToAddress(
scval: any // : SorobanClient.xdr.ScVal | undefined
Expand All @@ -13,3 +13,16 @@ export function scValToAddress(
return 'unknown address type ...'
}
}

export const scValToString = (scVal: any) => {
console.log(`type ${scVal.switch ? scVal.switch().name : 'unknown'}`)
const native = scValToNative(scVal)
console.log(`type: ${typeof native} val: ${native}`)
if (typeof native === 'string') {
return native
} else if (typeof native === 'bigint') {
return native.toString()
} else {
return JSON.stringify(native)
}
}
42 changes: 32 additions & 10 deletions app/routes/contract.$contractId.storage.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,40 @@
import { useLoaderData, useParams } from "@remix-run/react"
import { LoaderArgs, json } from "@remix-run/node"
import { useEffect } from "react"
import Table from "react-bootstrap/Table"

import { xdr } from '~/lib/stellar'
import { getContractInfo } from "~/lib/stellar/contracts"
import { StorageElement, getContractInfo } from "~/lib/stellar/contracts"
import { requestToSorobanServer } from "~/lib/stellar/server"
import { setTitle } from "~/lib/utils"
import AccountLink from "~/components/shared/AccountLink"

const Storage = ({ storage }: { storage: ReadonlyArray<xdr.ScMapEntry> }) => (
<div id="contract-storage">
{storage.map(s => (
<div>{JSON.stringify(s)}</div>
))}
</div>
const Storage = ({ storage }: { storage: ReadonlyArray<StorageElement> }) => (
<Table id="storage-table">
<thead>
<th>Key</th>
<th>Value</th>
</thead>
<tbody>
{
storage.map(({ key, keyType, value, valueType }) => (
<tr key={key}>
<td>
<span>{key}</span>
&nbsp;&nbsp;&nbsp;&nbsp;<small><i>{`[${keyType.substring(3)}]`}</i></small>
</td>
<td>
<span title={valueType}>
{value === 'scvAddress' ?
<AccountLink account={value} /> : value
}
</span>
&nbsp;&nbsp;<small><i>{`[${valueType.substring(3)}]`}</i></small>
</td>
</tr>
))
}
</tbody>
</Table>
)

export const loader = ({ params, request }: LoaderArgs) => {
Expand All @@ -35,9 +57,9 @@ export default function StorageTab() {
}, [])

const loadResult = useLoaderData<typeof loader>() as
{ storage: ReadonlyArray<xdr.ScMapEntry> } | null
{ storage: ReadonlyArray<StorageElement> } | null

if (!loadResult) {
if (!loadResult || loadResult.storage.length == 0) {
return (<span>No storage</span>)
}

Expand Down
6 changes: 3 additions & 3 deletions app/routes/contract.$contractId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ export default function () {
<DetailRow label="contract.create.ledger">
<Link to={`/ledger/${wasmIdLedger}`}>{wasmIdLedger}</Link>
</DetailRow>
<DetailRow label="contract.wasm.upload.ledger">
<Link to={`/ledger/${wasmCodeLedger}`}>{wasmCodeLedger}</Link>
</DetailRow>
<DetailRow label="contract.wasm.id">
<span>
{wasmId}
<ClipboardCopy text={wasmId} />
</span>
</DetailRow>
<DetailRow label="contract.wasm.upload.ledger">
<Link to={`/ledger/${wasmCodeLedger}`}>{wasmCodeLedger}</Link>
</DetailRow>
</tbody>
</Table>
</Card.Body>
Expand Down
8 changes: 8 additions & 0 deletions app/styles/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,14 @@ pre#plain-text {
border: none;
}

.invoke-param {
padding-left: 10px;
}

.invoke-param:before {
content: "-> ";
}

#wasm-code>div {
margin-bottom: 20px;
}
Expand Down
24 changes: 12 additions & 12 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"react-json-pretty": "^2.2.0",
"react-router-bootstrap": "^0.26.2",
"remix-utils": "^6.6.0",
"soroban-client": "0.11.0",
"soroban-client": "0.11.2",
"stellar-sdk": "10.4.1",
"urijs": "1.19.11"
},
Expand All @@ -68,4 +68,4 @@
"eslint": "^8.46.0",
"typescript": "^5.1.6"
}
}
}

0 comments on commit f6f6c2c

Please sign in to comment.