Schema Compiler

Plugins & RPC

Define RPC plugins and methods for the Timeleap network.

The .sia schema language supports plugin definitions for building RPC (Remote Procedure Call) endpoints on the Timeleap network. A plugin groups related methods that can be called over the network.

Plugin Syntax

plugin swiss.timeleap.isWizard.v1 as Sorcery {
  method isWizard(timeout = 5000) {
    age       uint8
    name      string8
  } returns {
    isWizard  bool
    message   string8
  }
}

Plugin Name

The plugin name is a dot-delimited identifier that uniquely identifies it on the Timeleap network:

swiss.timeleap.isWizard.v1

Convention: {region}.{org}.{name}.{version}

Alias (as)

The as clause provides a short name used as the generated class name:

plugin swiss.timeleap.isWizard.v1 as Sorcery { ... }

If omitted, the compiler auto-generates a PascalCase name from the plugin identifier.

Methods

Each method has a name, optional parameters (type options), input fields, and return fields:

method methodName(timeout = 5000, fee = 100, currency = "TLP") {
  // input fields
} returns {
  // output fields
}

Method Options

OptionTypeDefaultDescription
timeoutNumber (ms)5000How long to wait for a response
feeNumber0Fee for calling this method
currencyString"TLP"Currency for the fee

Schema References as Parameters

Instead of inline field definitions, methods can reference existing schemas:

schema WizardRequest {
  age   uint8
  name  string8
}

schema WizardResponse {
  isWizard  bool
  message   string8
}

plugin swiss.timeleap.isWizard.v1 as Sorcery {
  method isWizard(timeout = 5000) WizardRequest returns WizardResponse
}

Code Generation

TypeScript is the only language with full plugin code generation. The compiler produces a class with:

  • A connect static factory method
  • Lazy-cached method instances via a Map
  • Async methods that serialize parameters, invoke the RPC, and deserialize the response
import { Sia } from "@timeleap/sia";
import { Client, Function } from "@timeleap/client";

export class Sorcery {
  private methods: Map<string, Function> = new Map();
  private pluginName = "swiss.timeleap.isWizard.v1";

  constructor(private client: Client) {}

  static connect(client: Client): Sorcery {
    return new Sorcery(client);
  }

  private getMethod(
    method: string,
    timeout: number,
    fee: { currency: string; amount: number },
  ): Function {
    if (!this.methods.has(method)) {
      this.methods.set(
        method,
        this.client.method({
          plugin: this.pluginName,
          method,
          timeout,
          fee,
        }),
      );
    }
    return this.methods.get(method)!;
  }

  public async isWizard(
    sia: Sia,
    age: number,
    name: string[],
  ): Promise<{
    isWizard: boolean;
    message: string;
  }> {
    sia.addUInt8(age);
    sia.addArray8(name, (s: Sia, v) => sia.addString8(v));
    const method = this.getMethod("isWizard", 5000, {
      currency: "TLP",
      amount: 0,
    });
    const response = await method.populate(sia).invoke();
    const respIsWizard = response.readBool();
    const respMessage = response.readString8();
    return {
      isWizard: respIsWizard,
      message: respMessage,
    };
  }
}

Usage

import { Client } from "@timeleap/client";
import { Sia } from "@timeleap/sia";
import { Sorcery } from "./schema";

const client = new Client(/* connection config */);
const sorcery = Sorcery.connect(client);

const sia = new Sia();
const result = await sorcery.isWizard(sia, 25, ["Gandalf"]);
console.log(result.isWizard); // true
console.log(result.message); // "You shall pass!"

Go does not yet support plugin code generation. The compiler emits a comment stub:

// Cannot generate plugin 'swiss.timeleap.isWizard.v1' due to lack of
// RPC support in the Go Sia generator.
// You must connect to this plugin manually via RPC.
// https://timeleap.swiss/docs/products/sia/highlevel#rpc

Python does not yet support plugin code generation. The compiler emits a comment stub:

# Cannot generate plugin 'swiss.timeleap.isWizard.v1' due to lack of
# RPC support in the Python Sia generator.
# You must connect to this plugin manually via RPC. Please check the tutorial below:
# https://timeleap.swiss/docs/products/sia/highlevel#rpc

C++ does not yet support plugin code generation. The compiler emits a comment stub:

// Plugin 'swiss.timeleap.isWizard.v1' is not supported in C++ generator.

Multiple Methods

A plugin can have multiple methods:

plugin swiss.timeleap.math.v1 as MathService {
  method add(timeout = 3000) {
    a  int32
    b  int32
  } returns {
    result  int32
  }

  method multiply(timeout = 3000) {
    a  int32
    b  int32
  } returns {
    result  int64
  }

  method divide(timeout = 5000, fee = 10) {
    numerator    int64
    denominator  int32
  } returns {
    quotient   int64
    remainder  int32
  }
}

Each method becomes a separate async method on the generated class.