Skip to content

Commit

Permalink
feat: make hex string use directly
Browse files Browse the repository at this point in the history
  • Loading branch information
jeasonstudio committed May 7, 2024
1 parent 2ff9b9d commit cfd8053
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 141 deletions.
129 changes: 53 additions & 76 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,115 +49,92 @@ $ npm install @ordjs/runestone

### Runestone

```javascript
import { Runestone } from '@ordjs/runestone';
Rune protocol messages, called runestones, are stored in Bitcoin transaction outputs.

#### Decipher Runestones

```typescript
import { Runestone, Transaction } from '@ordjs/runestone';

// decipher
// See https://mempool.space/tx/2bb85f4b004be6da54f766c17c1e855187327112c231ef2ff35ebad0ea67c69e
const tx = {
const tx: Transaction = {
output: [{
// // OP_RETURN OP_PUSHNUM_13 ...
script_pubkey: '6a5d1f02010480bbb180c5ddf4ede90303a40805b5e9070680809dd085bedd031601',
value: 0,
}],
};

const runestone = Runestone.decipher(tx);
console.log(JSON.stringify(runestone.toString()));
/*
{
"edicts": [],
"etching": {
"divisibility": 2,
"premine": 11000000000,
"rune": {
"value": 67090369340599845000
},
"spacers": 7967,
"symbol": "ᚠ",
"terms": {
"amount": 100,
"cap": 1111111,
"height": {
"start": null,
"end": null
},
"offset": {
"start": null,
"end": null
}
},
"turbo": true
},
"mint": null,
"pointer": null
}
*/


// encipher
console.log(runestone.encipher());
// 6a5d21020704b5e1d8e1c8eeb788a3070102039f3e05a02d0680dc9afd280a6408c7e843
// runestone.divisibility => 2
// runestone.premine => 11000000000
// runestone.symbol => ᚠ
// runestone.terms.amount => 100
```

### Rune ID
#### Encipher Runestones

```javascript
import { RuneId } from '@ordjs/runestone';
To deploy a new rune ticker, this will require a commitment in an input script.

const runeId = new RuneId(840000n, 1);
```typescript
import { Runestone, Etching, SpacedRune, Terms } from '@ordjs/runestone';

console.log('runeId:', runeId.toString(), runeId.block, runeId.tx); // 840000:1 840000n 1
console.log('delta:', runeId.delta(new RuneId(840001n, 10000)).start); // 1n
console.log('next:', runeId.next(1n, 1).toString()); // 840001:1
console.log(RuneId.fromString('840000:1').toString()); // 840000:1
```
const etching = new Etching(SpacedRune.fromString('HI•JEASON'));
etching.terms = new Terms(69n, 420n);
etching.divisibility = 0;
etching.premine = 0n;
etching.symbol = '$';

### Rune
const runestone = new Runestone();
runestone.etching = etching;

```javascript
import { Rune } from '@ordjs/runestone';
console.log(runestone.encipher());
// 6a5d16020704b7fcb396fa0101000302052406000a4508a403
// send runestone.encipher() to the blockchain
```

const rune = new Rune(67090369340599840949n);
To mint `UNCOMMON•GOODS`:

console.log('value:', rune.value); // 67090369340599840949n
console.log('isReserved:', rune.isReserved()); // false
console.log('name:', rune.toString()); // ZZZZZFEHUZZZZZ
console.log('commitment:', rune.commitment());
// Uint8Array(9) [181, 48, 54, 140, 116, 223, 16, 163, 3]
```typescript
import { Runestone, RuneId } from '@ordjs/runestone';

console.log(Rune.firstRuneHeight('main')); // 840000
console.log(Rune.fromString('ZZZZZFEHUZZZZZ').value); // 67090369340599840949n
const runestone = new Runestone();
runestone.mint = new RuneId(1n, 0);

console.log(runestone.encipher());
// 6a5d0414011400
// send runestone.encipher() to the blockchain
```

### Spaced Rune
Transfer 10 `UNCOMMON•GOODS` to output 1:

```javascript
import { SpacedRune, Rune } from '@ordjs/runestone';
```typescript
import { Runestone, Edict, RuneId } from '@ordjs/runestone';

const rune = new Rune(67090369340599840949n);
const spacedRune = new SpacedRune(rune, 7967);
const edict = new Edict(new RuneId(1n, 0), 10n, 1);
const runestone = new Runestone();
runestone.edicts = [edict];

console.log('spaced rune:', spacedRune.toString()); // Z•Z•Z•Z•Z•FEHU•Z•Z•Z•Z•Z
console.log(
'rune value:',
SpacedRune.fromString('Z•Z•Z•Z•Z•FEHU•Z•Z•Z•Z•Z').rune.value // 67090369340599840949n
);
console.log(
'rune spacers:',
SpacedRune.fromString('Z•Z•Z•Z•Z•FEHU•Z•Z•Z•Z•Z').spacers // 7967
);
console.log(runestone.encipher());
// 6a5d050001000a01
// send runestone.encipher() to the blockchain
```

## Use in Browser

We provide the output format of ESM bundles for easy use in browsers directly:

```html
<script type="module">
import { Rune } from 'https://esm.sh/@ordjs/runestone@latest/bundle';
const rune = new Rune(1n);
console.log(rune.toString());
import { Runestone } from 'https://esm.sh/@ordjs/runestone/bundle';
const rs = Runestone.decipher({...});
console.log(JSON.stringify(rs));
</script>
```

For more usage, please refer to the [examples](/examples/) directory.

## License

[MIT](./LICENSE)
12 changes: 12 additions & 0 deletions examples/etching.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { SpacedRune, Terms, Etching } from '../runestone/index.js';

const spacedRune = SpacedRune.fromString('Z•Z•Z•Z•Z•FEHU•Z•Z•Z•Z•Z');
const etching = new Etching(spacedRune);
console.log(JSON.stringify(etching));

etching.terms = new Terms(420n, 2n);
etching.divisibility = 2;
etching.premine = 100n;
etching.symbol = '?';
etching.turbo = false;
console.log(JSON.stringify(etching));
42 changes: 16 additions & 26 deletions examples/runestone.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import {
Edict,
Etching,
Range,
Rune,
RuneId,
Runestone,
SpacedRune,
Terms,
Expand Down Expand Up @@ -33,7 +36,8 @@ console.log(
Runestone.decipher({
output: [
{
script_pubkey: '51206da59bfd6b08756375d62e8e38e55db6edaaf20a12b3e6e7f3aa36afcfc3c931',
script_pubkey:
'51206da59bfd6b08756375d62e8e38e55db6edaaf20a12b3e6e7f3aa36afcfc3c931',
value: 0,
},
{
Expand Down Expand Up @@ -63,29 +67,15 @@ console.log(
)
);

// const spacedRune = SpacedRune.fromString('Z•Z•Z•Z•Z•FEHU•Z•Z•Z•Z•Z');
// const terms = new Terms({
// amount: 420n,
// cap: 69n,
// offset: {
// end: 9001n,
// },
// });
// Terms.fromJSON({
// amount: 420n,
// cap: 69n,
// offset: {
// end: 9001n,
// },
// });
const rs = new Runestone();

// const etching = new Etching({
// rune: spacedRune.rune,
// spacers: spacedRune.spacers,
// divisibility: 2,
// premine: 0,
// symbol: '',
// terms,
// turbo: true,
// });
// console.log(etching);
const terms = new Terms(69n, 420n);
const etching = new Etching(SpacedRune.fromString('HI•JEASON'));
etching.premine = 100n;
etching.terms = terms;
rs.etching = etching;

const edict = new Edict(new RuneId(840000n, 1), 10000n, 0);
rs.edicts = [edict];
console.log(JSON.stringify(rs, null, 2));
console.log(rs.encipher());
10 changes: 10 additions & 0 deletions examples/terms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Range, Terms } from '../runestone/index.js';

const terms = new Terms(420n, 2n);
console.log(JSON.stringify(terms));

terms.height = new Range(1n, 2n);
console.log(JSON.stringify(terms));

terms.offset = new Range(1n, 2n);
console.log(JSON.stringify(terms));
45 changes: 43 additions & 2 deletions src/etching.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::rune::*;
use super::spaced_rune::*;
use super::terms::*;
use gloo_utils::format::JsValueSerdeExt;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -35,8 +36,17 @@ pub struct Etching {
#[wasm_bindgen]
impl Etching {
#[wasm_bindgen(constructor)]
pub fn new(etching: Option<Etching>) -> Etching {
etching.unwrap_or_default()
pub fn new(spaced_rune: SpacedRune) -> Etching {
let source = ordinals::Etching {
divisibility: None,
premine: None,
rune: Some(spaced_rune.rune.source),
spacers: Some(spaced_rune.spacers),
symbol: None,
terms: None,
turbo: true,
};
Etching::from(source)
}

#[wasm_bindgen(getter)]
Expand All @@ -47,6 +57,37 @@ impl Etching {
}
}

#[wasm_bindgen(js_name = "divisibility", setter)]
pub fn set_divisibility(&mut self, values: u8) {
self.source.divisibility = Some(values);
self.divisibility = Some(values);
}

#[wasm_bindgen(js_name = "premine", setter)]
pub fn set_premine(&mut self, values: js_sys::BigInt) {
let value: u128 = values.try_into().unwrap();
self.source.premine = Some(value);
self.premine = Some(value);
}

#[wasm_bindgen(js_name = "symbol", setter)]
pub fn set_symbol(&mut self, values: char) {
self.source.symbol = Some(values);
self.symbol = Some(values);
}

#[wasm_bindgen(js_name = "terms", setter)]
pub fn set_terms(&mut self, values: Terms) {
self.source.terms = Some(values.source);
self.terms = Some(values);
}

#[wasm_bindgen(js_name = "turbo", setter)]
pub fn set_turbo(&mut self, values: bool) {
self.source.turbo = values;
self.turbo = values;
}

#[wasm_bindgen]
pub fn supply(&self) -> Option<u64> {
match self.source.supply() {
Expand Down
53 changes: 25 additions & 28 deletions src/runestone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,9 @@ pub struct Runestone {
#[wasm_bindgen]
impl Runestone {
#[wasm_bindgen(constructor)]
pub fn new(
edicts: Vec<Edict>,
etching: Option<Etching>,
mint: Option<RuneId>,
pointer: Option<u32>,
) -> Self {
let edicts_source = edicts.iter().map(|&edict| edict.source).collect();
let etching_source = match etching {
Some(etching) => Some(etching.source),
None => None,
};
let mint_source = match mint {
Some(mint) => Some(mint.source),
None => None,
};
let source = ordinals::Runestone {
edicts: edicts_source,
etching: etching_source,
mint: mint_source,
pointer,
};
Self {
edicts,
etching,
mint,
pointer,
source,
}
pub fn new() -> Self {
let default = ordinals::Runestone::default();
Self::from(default)
}

#[wasm_bindgen(js_name = "edicts", getter)]
Expand Down Expand Up @@ -158,3 +133,25 @@ impl Runestone {
JsValue::from_serde(&self).unwrap()
}
}

impl From<ordinals::Runestone> for Runestone {
fn from(source: ordinals::Runestone) -> Self {
Self {
edicts: source
.edicts
.iter()
.map(|&edict| Edict::from(edict))
.collect(),
etching: match source.etching {
Some(etching) => Some(Etching::from(etching)),
None => None,
},
mint: match source.mint {
Some(mint) => Some(RuneId::from(mint)),
None => None,
},
pointer: source.pointer,
source,
}
}
}
Loading

0 comments on commit cfd8053

Please sign in to comment.