rjsvm
v0.4.1
Published
[](https://www.npmjs.com/package/rjsvm) [](https://www.npmjs.com/package/rjsvm) [
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";
// Begin by defining the parameter type using Zod
const blogpostSchema = z.object({
title: z.string(),
body: z.string(),
from: z.string(),
})
type Blogpost = z.infer<typeof blogpostSchema>
// Define the shape of the state the RJSVM will manipulate
type State = {
data: Blogpost[]
}
// Define the RJSVM endpoints
type RJSVMEndpoints = {
submit: (data: Blogpost) => void
ownerSubmit: (data: Blogpost) => void
remove: (data: Blogpost) => void
}
// Define initial RJSVM state. The 'owner' and 'state' fields are both required.
abstract class RJSVM_Base
extends RJSVM<State, RJSVMEndpoints>
implements RJSVM_Interface<RJSVM_Base> {
owner = ownerWallet.address
state: State = {
blogposts: []
}
}
// Implement the program logic
const RJSVM_Contract: RJSVM_Implementations<RJSVM_Base> = {
// Endpoints may declare a minimum fee in order to be applied
submit: {
implementation: function (env, data) {
this.state.blogposts.unshift(data)
},
visibility: 'public',
fee: 10,
parameterSchema: blogpostSchema
},
// Endpoints can be owner-exclusive in order to grant free access
ownerSubmit: {
implementation: function (env, shout) {
this.state.blogposts.unshift(shout)
},
visibility: 'owner',
parameterSchema: blogpostSchema
},
// Owner-exclusive endpoints can also be used to implement protected functionality
remove: {
implementation: function (env, data) {
this.state.blogposts = this.state.blogposts.filter(post => post.title != post.title)
},
visibility: 'owner',
parameterSchema: blogpostSchema,
}
}
// Finally build and connect the RJSVM
const Rjsvm = RJSVM_Builder.from(RJSVM_Base, RJSVM_Contract);
const conf: RJSVM_Config = {
listeningAddress: listeningWallet.address, // The XRP address to check for endpoint calls
rippleNode: "wss://s.altnet.rippletest.net:51233" // Any online XRP node connected to the right chain
}
const rjsvm = new Rjsvm(conf)
rjsvm.connect()Datawriter
import { Datawriter } from "rjsvm";
const datawriter = new Datawriter({
sendWallet: userWallet, // A wallet controlled by the user
receiveAddress: drainWallet.address, // A secondary address controlled by the user
xrpNode: xrpNode, // Any online XRP node connected to the right chain
contractAddress: listeningWallet.address // The XRP associated with the RJSVM
})
datawriter.callEndpoint('submit', {
title: "My first blogpost",
body: "Hello hello this is a blogpost!",
from: "#1 RJSVM User in the world"
}, 10)
// once the ripple blockchain persists the transaction, all copies of the RJSVM defined above will contain this blogpost
datawriter.callEndpoint('submit', {
title: "A underfunded blogpost",
body: "Oh no this will never show up!",
from: "#1 RJSVM User in the world"
})
// Insufficient fee, the RJSVMs will not contain this blogpost. No refunds.
datawriter.ownerSubmit('ownerSubmit', {
title: "A underprivileged blogpost",
body: "Oh no this will never show up!",
from: "#1 RJSVM User in the world"
})
// userWallet.address != ownerWallet.address, the RJSVMs will not contain this blogpost.