Skip to content

Commit

Permalink
Inscription Example
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremyRubin committed Jan 22, 2024
1 parent 8b6c571 commit 387e990
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 1 deletion.
3 changes: 2 additions & 1 deletion plugin-example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ members = ["treepay"
, "nft-auction"
, "clause-module"
, "clause-module-trampoline"
, "ordinal-example"]
, "ordinal-example"
, "ordinal-inscription"]
60 changes: 60 additions & 0 deletions plugin-example/ordinal-inscription/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
[package]
name = "sapio-wasm-ordinal-inscription"
version = "0.1.0"
license = "MPL-2.0"
authors = ["Jeremy Rubin <[email protected]>"]
edition = "2021"
repository = "https://github.com/sapio-lang/sapio"
homepage = "https://sapio-lang.org"
description = "An Example Sapio Application"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["cdylib", "rlib"]
path = "src/plugin.rs"
[package.metadata.wasm-pack.profile.release]
wasm-opt = false

[dependencies]
serde_json = "1.0"
serde = "1.0"
serde_derive = "1.0"


[dependencies.schemars]
version = "0.8.0"
features = ['impl_json_schema']
[dependencies.bitcoin]
package = "sapio-bitcoin"
version = "0.28.0"
features = ['use-serde']
[dependencies.sapio]
path = "../../sapio"
version = "0.2.0"

[dependencies.batching-trait]
path = "../batching-trait"
version = "0.1.0"

[dependencies.sapio-base]
path = "../../sapio-base"
version = "0.2.0"
[dependencies.sapio-contrib]
path = "../../sapio-contrib"
version = "0.2.0"


[dependencies.sapio-ctv-emulator-trait]
path = "../../emulator-trait"
version = "0.2.0"


[dependencies.sapio-wasm-plugin]
path = "../../plugins"
version = "0.2.0"
features = ["client"]

[dependencies.sapio-wasm-nft-trait]
path = "../nft-trait"
version = "0.1.0"
6 changes: 6 additions & 0 deletions plugin-example/ordinal-inscription/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Sapio Vault Example

This crate can be compiled with `wasm-pack build`. The `*.wasm` artifact will
be created in the `pkg` directory, not in `target`.

Feel free to modify this code to experiment with creating your own Sapio plugins.
Binary file added plugin-example/ordinal-inscription/src/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
109 changes: 109 additions & 0 deletions plugin-example/ordinal-inscription/src/plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use bitcoin::util::amount::Amount;
use bitcoin::Address;
use bitcoin::XOnlyPublicKey;
use sapio::contract::CompilationError;
use sapio::contract::Compiled;
use sapio::contract::Contract;
use sapio::contract::StatefulArgumentsTrait;
use sapio::ordinals::OrdinalPlanner;
use sapio::util::amountrange::AmountU64;
use sapio::*;
use sapio_base::Clause;
use sapio_wasm_plugin::*;
use schemars::*;
use serde::*;
/// # SimpleInscription
/// A really Ordinal Bearing Contract
#[derive(JsonSchema, Serialize, Deserialize)]
pub struct InscribingStep {
#[schemars(with = "bitcoin::hashes::sha256::Hash")]
owner: XOnlyPublicKey,
data: Vec<u8>,
content_type: String,
}
impl InscribingStep {
/// # signed
/// Get the current owners signature.
#[guard]
fn signed(self, _ctx: Context) {
Clause::Key(self.owner)
}

#[guard]
fn inscription(self, _ctx: Context) {
let insc = sapio_base::miniscript::ord::Inscription::new(
Some(self.content_type.as_bytes().into()),
Some(self.data.clone()),
);
Clause::Inscribe(Box::new(insc), Box::new(Clause::Trivial))
}
}

#[derive(JsonSchema, Serialize, Deserialize)]
pub struct Reveal {
fee: AmountU64,
alternative: Option<Address>,
}
impl Reveal {
fn parse(
k: <InscribingStep as sapio::contract::Contract>::StatefulArguments,
) -> Result<Self, CompilationError> {
Ok(k)
}
}
impl Default for Reveal {
fn default() -> Self {
Self {
fee: Amount::from_sat(500).into(),
alternative: None,
}
}
}
// ASSUMES 500 sats after Ord are "dust"
impl InscribingStep {
#[continuation(
guarded_by = "[Self::signed, Self::inscription]",
web_api,
coerce_args = "Reveal::parse"
)]
fn reveal(self, ctx: Context, reveal: Reveal) {
let ord = ctx
.get_ordinals()
.as_ref()
.ok_or_else(|| CompilationError::OrdinalsError("Missing Ordinals Info".into()))?
.0[0]
.0;
let funds = ctx.funds();
if funds < Amount::from(reveal.fee) + ord.padding() + Amount::ONE_SAT {
return Err(CompilationError::OutOfFunds);
}
let send_with = funds - reveal.fee.into();
let tmpl = ctx.template();
if let Some(address) = reveal.alternative {
tmpl.add_output(send_with, &Compiled::from_address(address, None), None)
} else {
tmpl.add_output(send_with, &self.owner, None)
}?
.add_fees(reveal.fee.into())?
.into()
}
}
impl StatefulArgumentsTrait for Reveal {}

/// # The SimpleInscription Contract
impl Contract for InscribingStep {
declare! {updatable<Reveal>, Self::reveal}

fn ensure_amount(&self, ctx: Context) -> Result<Amount, CompilationError> {
// Optional if we want to require ordinal info provided -- we can
// happily track ordinals abstractly with some future patches.
let ords = ctx
.get_ordinals()
.as_ref()
.ok_or_else(|| CompilationError::OrdinalsError("Missing Ordinals Info".into()))?;
Ok(ords.total())
}
}


REGISTER![InscribingStep, "logo.png"];

0 comments on commit 387e990

Please sign in to comment.