Skip to content

Executing Methods

mero.rpc executes methods on the WASM application inside a context. It speaks JSON-RPC 2.0 to the node’s /jsonrpc endpoint and decodes the method’s return value straight into your Decodable type.

struct Post: Decodable { let id: String; let title: String }
let post: Post = try await mero.rpc.execute(
contextId: "…",
method: "get_post",
argsJson: ["id": "42"]
)
  • contextId — the context to run in.
  • method — the contract method name.
  • argsJson — a [String: JSONValue] of named arguments (defaults to [:]).
  • The return type is inferred from the call site; execute decodes result.output into it.

argsJson is a [String: JSONValue]. JSONValue conforms to the Swift ExpressibleBy…Literal protocols, so you write ordinary literals — strings, numbers, bools, arrays, and nested objects — with no wrapping:

let args: [String: JSONValue] = [
"id": "42",
"limit": 10,
"verbose": true,
"tags": ["a", "b"],
"filter": ["author": "alice"],
]
let result: MyResult = try await mero.rpc.execute(
contextId: contextId, method: "search", argsJson: args
)

If you don’t need a typed result, decode into JSONValue and use its accessors (.stringValue, .intValue, .arrayValue, subscript(key:), …):

let raw: JSONValue = try await mero.rpc.execute(
contextId: contextId, method: "get_state", argsJson: [:]
)
let name = raw["name"]?.stringValue

A JSON-RPC error from the contract throws MeroError.rpc(RpcError):

do {
let r: Receipt = try await mero.rpc.execute(
contextId: contextId, method: "transfer", argsJson: ["to": to, "amount": 10])
} catch let error as MeroError {
if case .rpc(let rpc) = error {
print("contract error \(rpc.code): \(rpc.message)", rpc.data as Any)
}
throw error
}

RpcError carries code, message, an optional type, and optional data (JSONValue?). Transport failures (HTTP 4xx/5xx, network) are MeroError.http / .network, not .rpc — see the error model.

Two convenience wrappers over execute support the entry-migration flow used when an application upgrades its state schema:

let summary = try await mero.rpc.migrateMyEntries(contextId) // .converted, .remaining
let pending = try await mero.rpc.countMyPending(contextId) // Int