Skip to content

Commit dad40a7

Browse files
authored
Release 0.2.0 (#10)
* Index statistic page. * List of reserved named without corroborating Nostr events. * Changelog update, update cargo.toml for v0.2.0. * Bold the message on the uncorroborated claims screen. * Clarifying language in the spec. * Handle edge case where a name is being indexed twice because it was posted with the same NSID twice. * CHANGELOG.md * Updating SPEC to remove transfers and added an Appendix for changes and updates. * Removing transfers from version 0x00 * Limiting names to 43 characters. * Use Primal.net for user links. * Index Stats was still using transfer_events table
1 parent 3abdcc3 commit dad40a7

26 files changed

+376
-327
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ nomen.db
1313
records1.json
1414
*.csv
1515
*.psbt
16-
release/
16+
release/
17+
*.bak

CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## 0.2.0
4+
5+
This release includes a database migration, so make sure to back up your index before upgrading.
6+
7+
Features:
8+
- Transfers have been removed, and names have been limited to 43 characters for vesion `0x00`. They will be enabled in the next version with a better designed.
9+
- Primal.net is now used to npub links.
10+
- New page to list blockchain claims for which there are no indexed record events.
11+
- Index statistic page.
12+
13+
Bugs:
14+
- Fixed a bug where a name was double-indexed because the same `OP_RETURN` was uploaded twice
15+
316
## 0.1.1
417

518
Features:

Cargo.lock

+13-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
[package]
22
name = "nomen"
3-
version = "0.1.1"
3+
version = "0.2.0"
44
edition = "2021"
5+
build = "build.rs"
56

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

@@ -35,3 +36,6 @@ time = { version = "0.3.20", features = ["formatting", "macros"] }
3536
tokio = { version = "1.26.0", features = ["full"] }
3637
toml = "0.7.2"
3738
yansi = "0.5.1"
39+
40+
[build-dependencies]
41+
vergen = { version = "8.0.0", features = ["build", "git", "gitcl"] }

build.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use std::error::Error;
2+
use vergen::EmitBuilder;
3+
4+
fn main() -> Result<(), Box<dyn Error>> {
5+
// Emit the instructions
6+
EmitBuilder::builder().all_build().all_git().emit()?;
7+
Ok(())
8+
}

docs/SPEC.md

+13-11
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,29 @@ Indexers (like a DNS name server) link on-chain claims to published Nostr events
1414

1515
### Blockchain
1616

17-
In order to claim a name, publish an output to the bitcoin blockchain in this format: `OP_RETURN <VERSION><TRANSACTION TYPE><NAME FINGERPRINT><NAMESPACE ID>`. All names have an associated owner, which just a private/public keypair. Public keys are always 32-byte X-Only Public Keys used everywhere in Nostr and Bitcoin Schnorr signatures.
17+
In order to claim a name, publish an output to the bitcoin blockchain in this format: `OP_RETURN NOM <VERSION> <TRANSACTION TYPE> <NAME FINGERPRINT> <NAMESPACE ID>`. The spaces are for readability and not significant. Do not include spaces in the final `OP_RETURN`. All names have an associated owner, which just a private/public keypair. Public keys are always 32-byte X-Only Public Keys used everywhere in Nostr and Bitcoin Schnorr signatures.
18+
19+
`NOM` is just the byte string "NOM", a tag indicator to let the indexer know this ia Nomen output.
1820

1921
`VERSION` is reserved for future use, for incompatible changes to the protocol, or unlocking additional namespace. It is one byte and must currently be `0x00`.
2022

2123
`TRANSACTION TYPE` represents the type of claim being made on chain. It is one byte. It may be `0x00` which represents a new name being claimed, or `0x01` which represents an ownership change of the name (owned by a new keypair).
2224

2325
`NAME FINGERPRINT` is the first five bytes of the HASH-160 of the name. The purpose is to allow a name to be verified as unreserved, even if a Nostr event cannot be found to prove it.
2426

25-
`NAMESPACE ID` represents a HASH-160 (20-byte) hash of the ownership information for this name. If the `TRANSACTION TYPE` is `0x00` (new name) then the `NAMESPACE ID` is the HASH-160 of `<NAME><OWNER PUBKEY>`. If the `TRANSACTION TYPE` is `0x01` (ownership change), then the `NAMESPACE ID` is the HASH-160 of `<NAME><NEW OWNER PUBKEY>`.
27+
`NAMESPACE ID` represents a HASH-160 (20-byte) hash of the ownership information for this name. If the `TRANSACTION TYPE` is `0x00` (new name) then the `NAMESPACE ID` is the HASH-160 of `<NAME><OWNER PUBKEY>`. Please be aware that the pubkey is a 32-byte byte string of the pubkey, not any textual representation such as bech32 or hexadecimal.
2628

2729
**Note:** The owner of the Bitcoin UTXO that generated the `OP_RETURN`, or the amount in the UTXO, do not matter. Bitcoin, in this case, is being utilized only as a decentralized timestamp server. The only thing that matters is the order of transaction outputs.
2830

2931
### Nostr
3032

3133
Nostr is the propogation layer of the protocol. The only required information on-chain is the information necessary to determination ownership of a name, and that is only in a shortened hash form.
3234

33-
There are currently three types of Nostr events. These are all parameterized replaceable events (all events are idempotent and thus replaceable).
35+
There is one new kind of Nostr event. It is a parameterized replaceable event (all events are idempotent and thus replaceable).
3436

3537
| Event kind | Event type | Description |
3638
|------------|---------------|---------------------------------------------------------------|
3739
| 38300 | NAME | Matches `0x00` tranaction type. Publishes records for a name. |
38-
| 38301 | TRANSFER NAME | Match to `0x01` transaction type |
3940

4041
#### New Name
4142

@@ -45,19 +46,13 @@ When the records need to be updated, the owner may just publish another name eve
4546

4647
**Note:** When receiving new events, and indexer should recalculate the namespace ID and compare to the `d` tag to validate the event, then use the namespace ID to link to blockchain for correct ordering. Indexers should also treat any blockchain transactions with mis-matching name fingerprints as invalid.
4748

48-
#### Transfer
49-
50-
After publishing a `0x01` transfer transaction, publish a `38301` kind Nostr event. The `d` tag for the event should be the lower case hex representation of the `NAMESPACE ID` published to the blockchain. Additionally, there should be a `nom` tag with the `name` value as the parameter. `content` must be lowercase hex encoded value of the pubkey of the **_new_** owner. The published event must be signed by the current owner of the name, in order to properly establish chain of custody.
51-
52-
**Note:** When receiving new events, and indexer should recalculate the namespace ID and compare to the `d` tag to validate the event, then use the namespace ID to link to blockchain for correct ordering. Unlike publishing new names, the namespace ID in this case is not constructed from the pubkey of the original owner, but the pubkey of the **_new_** owner.
53-
5449
## Appendix A: Name format
5550

5651
It is necessary to limit the characters used in names. While it might be tempting to allow any valid UTF-8 string, there are good reasons not to do this. In the Unicode standards, there are sometimes different ways to the construct the same character, invisible characters, or "whitespace" characters that may not necessarily be rendered, etc. This could allow for malicious individuals to trick unsuspecting users into clicking/pasting incorrect names.
5752

5853
While it is desirable to have a wide range of characters and languages be usable, for the time being it is necessary to restrict the use of characters to the basic characters typically used in domain names today.
5954

60-
Names must match the following regular expression `[0-9a-z\-]{3,256}` and must be ignored by indexers otherwise.
55+
Names must match the following regular expression `[0-9a-z\-]{3,43}` and must be ignored by indexers otherwise.
6156

6257
## Appendix B: Protocol expansion
6358

@@ -88,3 +83,10 @@ There are no restrictions on key/value pairs, but they are recommended by conven
8883
| `WEB` | Full link for website (not necessarily the same as `DNS`) |
8984

9085
Others may arise later by addition or general public acceptance. The above listed are not required, but if the owner wishes to include any of this data in their records, it is recommended to use the above keys.
86+
87+
## Appendix ZZ: Changes and Updates
88+
89+
**2023-09-19**:
90+
- Given the issues cited [here](https://github.com/ursuscamp/nomen/issues/6), the design of transfers in `0x00` is not good and has been removed. As of the time of publication, no transfers have been issued by any users, so this is a not a breaking change.
91+
- A new version will be issued which will enable transfers, and an upgrade path will be available for version `0x00` names to `0x01` names. However, in order to link the `0x00` to `0x01` names on chain, the upgrade transaction will require the names to be put on chain in plain text, necessitating limiting them to a maximum of 43 bytes for now (80 byte OP_RETURN maximum - 5 bytes for Nomen metadata - 32 bytes for a public key). As of the time of publication, no names longer than 43 bytes have been issued, so this is a non-breaking change.
92+

src/config/cfg.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ use nostr_sdk::{
88
};
99
use sqlx::{sqlite, SqlitePool};
1010

11-
use super::{
12-
Cli, ConfigFile, NameNewSubcommand, NameTransferSubcommand, ServerSubcommand, Subcommand,
13-
};
11+
use super::{Cli, ConfigFile, NameNewSubcommand, ServerSubcommand, Subcommand};
1412

1513
#[derive(Clone, Debug)]
1614
pub struct Config {

src/config/cli.rs

+3-46
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ pub struct Cli {
6262
pub subcommand: Subcommand,
6363
}
6464

65-
#[derive(clap::Subcommand, Debug, Clone)]
65+
#[derive(clap::Subcommand, Debug, Clone, Default)]
6666
pub enum Subcommand {
6767
#[command(skip)]
68+
#[default]
6869
Noop,
6970

7071
/// Extra utilities
@@ -82,12 +83,6 @@ pub enum Subcommand {
8283
Server(ServerSubcommand),
8384
}
8485

85-
impl Default for Subcommand {
86-
fn default() -> Self {
87-
Subcommand::Noop
88-
}
89-
}
90-
9186
#[derive(clap::Subcommand, Debug, Clone)]
9287
pub enum UtilSubcommand {
9388
/// Generate a private/public keypair.
@@ -117,7 +112,7 @@ pub enum UtilSubcommand {
117112
/// The public key of the owner
118113
pubkey: XOnlyPublicKey,
119114

120-
/// Transaction kind. Possible values: create, transfer
115+
/// Transaction kind. Possible values: create
121116
kind: NomenKind,
122117
},
123118
}
@@ -156,9 +151,6 @@ pub enum NameSubcommand {
156151

157152
/// Broadcast a new record for your name.
158153
Record(NameRecordSubcomand),
159-
160-
/// Transfer a domain to a new keypair.
161-
Transfer(NameTransferSubcommand),
162154
}
163155

164156
#[derive(clap::Args, Debug, Clone)]
@@ -205,41 +197,6 @@ pub struct NameRecordSubcomand {
205197
pub privkey: Option<NostrSk>,
206198
}
207199

208-
#[derive(clap::Args, Debug, Clone)]
209-
pub struct NameTransferSubcommand {
210-
/// The name to broadcast records
211-
pub name: Name,
212-
213-
/// Public key of the new owner
214-
pub pubkey: XOnlyPublicKey,
215-
216-
/// The transaction to sign. May be a path to a PSBT file or a Base64 encoded PSBT string.
217-
pub psbt: String,
218-
219-
/// Specify your private key on the command line. May be useful for scripts. Beware of shell history!
220-
/// Will prompt if not provided.
221-
/// This is the private key of the current owner of the name.
222-
#[arg(short, long)]
223-
pub privkey: Option<NostrSk>,
224-
225-
/// JSON command output
226-
#[arg(short, long)]
227-
pub json: bool,
228-
229-
/// Broadcast the associated Nostr event
230-
#[arg(short, long)]
231-
pub broadcast: bool,
232-
233-
/// Verify against the index that the name is exists and is transferrable.
234-
/// Be sure to run the indexer first, or this is not very useful.
235-
#[arg(short, long)]
236-
pub validate: bool,
237-
238-
/// File path to write a serialized PSBT file
239-
#[arg(short, long)]
240-
pub output: Option<PathBuf>,
241-
}
242-
243200
#[derive(clap::Args, Debug, Clone)]
244201
pub struct TxInfo {
245202
/// The txid to use as input.

0 commit comments

Comments
 (0)