Overview
The Ripple JavaScript Virtual Machine, or RJSVM, aims to standardize and simplify the development of applications that employ the Ripple blockchain as state storage. Internally it employs xrpIO to read and write all necessary data.
How to install
npm i rjsvm
How it works
The JSVM package comes with two major parts: The RJSVM itself and the Datawriter. The former is used to define initial program state, callable endpoints, and the associated their associated logic. The Datawriter serves as the glue between users and a RJSVM.
Due to the blockchain's properties of providing persistent and absolutely ordered transactions every copy of a RJSVM will behave exactly identically.
In order to provide a more robust environment and quasi-typesafe execution this package also requires zod.
A basic example
RJSVM
import { RJSVM_Builder, RJSVM_Implementations, RJSVM_Interface, RJSVM, RJSVM_Config } from "rjsvm";
import { z } from "zod";
const blogpostSchema = z.object({
title: z.string(),
body: z.string(),
from: z.string(),
})
type Blogpost = z.infer<typeof blogpostSchema>
type State = {
data: Blogpost[]
}
type RJSVMEndpoints = {
submit: (data: Blogpost) => void
ownerSubmit: (data: Blogpost) => void
remove: (data: Blogpost) => void
}
abstract class RJSVM_Base
extends RJSVM<State, RJSVMEndpoints>
implements RJSVM_Interface<RJSVM_Base> {
owner = ownerWallet.address
state: State = {
blogposts: []
}
}
const RJSVM_Contract: RJSVM_Implementations<RJSVM_Base> = {
submit: {
implementation: function (env, data) {
this.state.blogposts.unshift(data)
},
visibility: 'public',
fee: 10,
parameterSchema: blogpostSchema
},
ownerSubmit: {
implementation: function (env, shout) {
this.state.blogposts.unshift(shout)
},
visibility: 'owner',
parameterSchema: blogpostSchema
},
remove: {
implementation: function (env, data) {
this.state.blogposts = this.state.blogposts.filter(post => post.title != post.title)
},
visibility: 'owner',
parameterSchema: blogpostSchema,
}
}
const Rjsvm = RJSVM_Builder.from(RJSVM_Base, RJSVM_Contract);
const conf: RJSVM_Config = {
listeningAddress: listeningWallet.address,
rippleNode: "wss://s.altnet.rippletest.net:51233"
}
const rjsvm = new Rjsvm(conf)
rjsvm.connect()
Datawriter
import { Datawriter } from "rjsvm";
const datawriter = new Datawriter({
sendWallet: userWallet,
receiveAddress: drainWallet.address,
xrpNode: xrpNode,
contractAddress: listeningWallet.address
})
datawriter.callEndpoint('submit', {
title: "My first blogpost",
body: "Hello hello this is a blogpost!",
from: "#1 RJSVM User in the world"
}, 10)
datawriter.callEndpoint('submit', {
title: "A underfunded blogpost",
body: "Oh no this will never show up!",
from: "#1 RJSVM User in the world"
})
datawriter.ownerSubmit('ownerSubmit', {
title: "A underprivileged blogpost",
body: "Oh no this will never show up!",
from: "#1 RJSVM User in the world"
})