Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tweaks the response for invoke host fns to expose fn name and args #20

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/helper/soroban-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
scValToNative,
xdr,
SorobanRpc,
StrKey,
} from "stellar-sdk";
import { NetworkNames } from "./validate";

Expand Down Expand Up @@ -139,8 +140,43 @@ const buildTransfer = (
return tx.build();
};

// https://github.com/stellar/soroban-examples/blob/main/token/src/contract.rs
enum SorobanTokenInterface {
transfer = "transfer",
mint = "mint",
}

const getOpArgs = (fnName: string, args: xdr.ScVal[]) => {
let amount: number;
let from;
let to;

switch (fnName) {
case SorobanTokenInterface.transfer:
from = StrKey.encodeEd25519PublicKey(
args[0].address().accountId().ed25519()
);
to = StrKey.encodeEd25519PublicKey(
args[1].address().accountId().ed25519()
);
amount = scValToNative(args[2]);
break;
case SorobanTokenInterface.mint:
to = StrKey.encodeEd25519PublicKey(
args[0].address().accountId().ed25519()
);
amount = scValToNative(args[1]).toString();
break;
default:
amount = 0;
}

return { from, to, amount };
};

export {
buildTransfer,
getOpArgs,
getServer,
getTokenBalance,
getTokenDecimals,
Expand Down
52 changes: 33 additions & 19 deletions src/service/mercury/helpers/transformers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { OperationResult } from "@urql/core";
import { Horizon, scValToNative, xdr } from "stellar-sdk";
import { Horizon, StrKey, scValToNative, xdr } from "stellar-sdk";
import BigNumber from "bignumber.js";
import {
BASE_RESERVE,
Expand All @@ -8,6 +8,7 @@ import {
getAssetType,
} from "../../../helper/horizon-rpc";
import { formatTokenAmount } from "../../../helper/format";
import { getOpArgs } from "../../../helper/soroban-rpc";

// Transformers take an API response, and transform it/augment it for frontend consumption

Expand Down Expand Up @@ -153,7 +154,9 @@ interface MercuryAccountHistory {
auth: string;
hostFunction: string;
sorobanMeta: string;
source: string;
accountBySource: {
publickey: string;
};
tx: string;
opId: string;
txInfoByTx: {
Expand Down Expand Up @@ -863,23 +866,34 @@ const transformAccountHistory = async (
): Promise<Partial<Horizon.ServerApi.OperationRecord>[]> => {
const invokeHostFnEdges =
rawResponse.data?.invokeHostFnByPublicKey.edges || [];
const invokeHostFn = invokeHostFnEdges.map(
(edge) =>
({
auth: edge.node.auth,
hostFunction: edge.node.hostFunction,
sorobanMeta: edge.node.sorobanMeta,
source: edge.node.source,
tx: edge.node.tx,
type: "invoke_host_function",
type_i: 24,
id: edge.node.opId,
transaction_attr: {
operation_count: edge.node.txInfoByTx.opCount,
fee_charged: edge.node.txInfoByTx.fee,
},
} as Partial<Horizon.ServerApi.InvokeHostFunctionOperationRecord>)
);
const invokeHostFn = invokeHostFnEdges.map((edge) => {
const hostFn = xdr.HostFunction.fromXDR(
Buffer.from(edge.node.hostFunction, "base64")
);
const invocation = hostFn.invokeContract();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what your requirements are in terms of operations you display, but it's worth pointing out that host invocations can also be create contract and uploadcontractwasm.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey thanks for the info there, the client ignores those types for now but we may pull those into history in the future as well.

const fnName = invocation.functionName().toString();
return {
auth: edge.node.auth,
created_at: new Date(
edge.node.txInfoByTx.ledgerByLedger.closeTime * 1000
).toISOString(),
sorobanMeta: edge.node.sorobanMeta,
source_account: edge.node.accountBySource.publickey,
tx: edge.node.tx,
type: "invoke_host_function",
type_i: 24,
id: edge.node.opId,
transaction_attr: {
contractId: StrKey.encodeContract(
invocation.contractAddress().contractId()
),
fnName,
args: getOpArgs(fnName, invocation.args()),
operation_count: edge.node.txInfoByTx.opCount,
fee_charged: edge.node.txInfoByTx.fee,
},
} as Partial<Horizon.ServerApi.InvokeHostFunctionOperationRecord>;
});

const createAccountEdges =
rawResponse.data?.createAccountByPublicKey.edges || [];
Expand Down
19 changes: 12 additions & 7 deletions src/service/mercury/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,11 +432,18 @@ export class MercuryClient {
} catch (error) {
this.logger.error(error);
const _error = JSON.stringify(error);
this.rpcErrorCounter
.labels({
rpc: "Horizon",
})
.inc();
if (error && typeof error === "object" && "message" in error) {
const err = JSON.parse(error.message as string);
// Not found errors are normal for unfunded accounts, dont alert
if (err.name !== "NotFoundError") {
this.rpcErrorCounter
.labels({
rpc: "Horizon",
})
.inc();
}
}

return {
data: null,
error: _error,
Expand All @@ -446,11 +453,9 @@ export class MercuryClient {

getAccountHistoryMercury = async (pubKey: string) => {
try {
const xdrPubKey = new Address(pubKey).toScVal().toXDR("base64");
const getData = async () => {
const data = await this.urqlClient.query(query.getAccountHistory, {
pubKey,
xdrPubKey,
});
const errorMessage = getGraphQlError(data.error);
if (errorMessage) {
Expand Down
18 changes: 14 additions & 4 deletions src/service/mercury/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,34 @@ export const query = {
contractId
keyXdr
valueXdr
ledgerTimestamp
ledger
entryDurability
txInfoByTx {
fee
opCount
txHash
ledger
ledgerByLedger {
closeTime
sequence
}
}
}
}
`
)}
}
`,
getAccountHistory: `
query GetAccountHistory($pubKey: String!, $xdrPubKey: String!) {
query GetAccountHistory($pubKey: String!) {
invokeHostFnByPublicKey(publicKeyText: $pubKey) {
edges {
node {
auth
hostFunction
sorobanMeta
source
accountBySource {
publickey
}
tx
opId
txInfoByTx {
Expand Down
Loading