mirror of
https://github.com/stjet/bns.git
synced 2025-12-29 11:19:25 +00:00
spec now at 1.0.0 release candidate
added domain freezing, suggest tld as domain receive rep, bug fixes
This commit is contained in:
7
LICENSE
Normal file
7
LICENSE
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Copyright 2024 stjet/Prussia
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,5 @@
|
|||||||
|
*Version 1.0.0 release-candidate*
|
||||||
|
|
||||||
Very similar to [Airtune's Banano NFT protocol](https://github.com/Airtune/73-meta-tokens)
|
Very similar to [Airtune's Banano NFT protocol](https://github.com/Airtune/73-meta-tokens)
|
||||||
|
|
||||||
In fact, though it is meant to be for domain names, it can actually be considered a sort of very limited NFT protocol.
|
In fact, though it is meant to be for domain names, it can actually be considered a sort of very limited NFT protocol.
|
||||||
@@ -69,13 +71,14 @@ Receives a Domain Transfer block. If not the opening block of the account, the r
|
|||||||
|
|
||||||
- Subtype: send
|
- Subtype: send
|
||||||
- Link (send block hash): Hash of the Domain Transfer block
|
- Link (send block hash): Hash of the Domain Transfer block
|
||||||
|
- Representative: Can *optionally* be the TLD account in order to make resolving backwards easier
|
||||||
|
|
||||||
## Domain Metadata block
|
## Domain Metadata block
|
||||||
|
|
||||||
To convey metadata associated with a block. Can only be sent by Domain Accounts
|
To convey metadata associated with a block. Can only be sent by Domain Accounts
|
||||||
|
|
||||||
- Subtype: change
|
- Subtype: change
|
||||||
- Representative: Hash of the metadata
|
- Representative: Hash of the metadata (**cannot be all 1s, then it is Domain Freeze**)
|
||||||
|
|
||||||
> Currently, it is recommended that this metadata hash be a translated IPFS v0 Cid, so metadata files should be hosted on IPFS. IPFS is not mandated by the protocol, and it is perfectly acceptable to use something that is not IPFS to store metadata and use a regular SHA-256 hash of the file. However, clients will likely only support finding IPFS metadata.
|
> Currently, it is recommended that this metadata hash be a translated IPFS v0 Cid, so metadata files should be hosted on IPFS. IPFS is not mandated by the protocol, and it is perfectly acceptable to use something that is not IPFS to store metadata and use a regular SHA-256 hash of the file. However, clients will likely only support finding IPFS metadata.
|
||||||
|
|
||||||
@@ -87,12 +90,12 @@ To change the what address the domain resolves to
|
|||||||
- Change in balance: 4224 raw
|
- Change in balance: 4224 raw
|
||||||
- Link (recepient): Banano address the domain should resolve to (typically the actual Banano address of the owner)
|
- Link (recepient): Banano address the domain should resolve to (typically the actual Banano address of the owner)
|
||||||
|
|
||||||
## Maybe: Domain Freeze block
|
## Domain Freeze block
|
||||||
|
|
||||||
All Domain Transfer blocks sent after this block are to be ignored. The domain becomes an "frozen domain". For a TLD account, prevents issuance of new domains for that TLD. For a Domain Account, prevents transfer of the domain currently held by it, as well as any change in resolving and metadata. Not the same as a burned domain for a Domain Account as frozen domains can still resolve to an address and have metadata, while burned domains cannot
|
All Domain Transfer blocks sent after this block are to be ignored. The domain becomes an "frozen domain". For a TLD account, prevents issuance of new domains for that TLD. For a Domain Account, prevents transfer of the domain currently held by it, as well as any change in resolving and metadata. Not the same as a burned domain for a Domain Account as frozen domains can still resolve to an address and have metadata, while burned domains cannot
|
||||||
|
|
||||||
- Subtype: change
|
- Subtype: change
|
||||||
- Representative: Pub key of all 0s
|
- Representative: Pub key (in hexadecimal) of "451", followed by sixty-two 1s
|
||||||
|
|
||||||
# Domain Metadata
|
# Domain Metadata
|
||||||
|
|
||||||
@@ -127,6 +130,8 @@ To resolve a domain to a Domain Account (after checking the domain name for vali
|
|||||||
|
|
||||||
The resolver should then go to the recipient of the Domain Transfer. If the opening block (height 1) is not a Domain Receive block for that Domain Transfer, then the resolver knows the domain has been burned, and the resolving process is over. The burned domain has no domain metadata or resolved address. If it does find the opening block is the Domain Receive block for that Domain Transfer, it should then crawl up the chain again, keeping note of any Domain Metadata or Domain Resolver blocks. Newer blocks replace the older ones. If it encounters a Domain Transfer block, it should discard the noted domain metadata and resolved address, and repeat. If it does not encounter a Domain Transfer block, and reaches the frontier (latest) block, then it should return the noted domain metadata and resolved address (or lack thereof).
|
The resolver should then go to the recipient of the Domain Transfer. If the opening block (height 1) is not a Domain Receive block for that Domain Transfer, then the resolver knows the domain has been burned, and the resolving process is over. The burned domain has no domain metadata or resolved address. If it does find the opening block is the Domain Receive block for that Domain Transfer, it should then crawl up the chain again, keeping note of any Domain Metadata or Domain Resolver blocks. Newer blocks replace the older ones. If it encounters a Domain Transfer block, it should discard the noted domain metadata and resolved address, and repeat. If it does not encounter a Domain Transfer block, and reaches the frontier (latest) block, then it should return the noted domain metadata and resolved address (or lack thereof).
|
||||||
|
|
||||||
|
Resolving backwards is also possible, but slightly more complicated. In the resolved address, look for any receives or pending transactions of 4242 raw in order to find Domain Accounts. If the resolver know what TLD address the domain is supposed to be, great. If not, try finding out by looking at the representative of the opening block (Domain Receive) of the found Domain Account. From the opening block's corresponding send (Domain Transfer), the resolver can find the domain name. Then, resolve like normal since the resolver now has the TLD address and domain name. After resolving, the resolver must check to make sure that the found domain account actually owns the domain.
|
||||||
|
|
||||||
## TLD (Issuing domains)
|
## TLD (Issuing domains)
|
||||||
|
|
||||||
A TLD operator can use whatever system it wants for issuing domain names. Some ideas are taking payments or issuing based on certain criteria (eg, citizenship). It should not issue invalid domain names. Even if it does, clients will ignore them. TLDs should also refuse to send to Banano accounts that already have blocks, because otherwise the domain name will be burned, which is probably not what the purchaser of the domain wants.
|
A TLD operator can use whatever system it wants for issuing domain names. Some ideas are taking payments or issuing based on certain criteria (eg, citizenship). It should not issue invalid domain names. Even if it does, clients will ignore them. TLDs should also refuse to send to Banano accounts that already have blocks, because otherwise the domain name will be burned, which is probably not what the purchaser of the domain wants.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as util from "./util";
|
import * as util from "./util";
|
||||||
|
export * from "./constants";
|
||||||
import * as resolver from "./resolver";
|
import * as resolver from "./resolver";
|
||||||
import * as manager from "./manager";
|
import * as manager from "./manager";
|
||||||
import * as types from "./types";
|
import * as types from "./types";
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
#main div {
|
#main div {
|
||||||
max-width: 50vw;
|
max-width: 50vw;
|
||||||
}
|
}
|
||||||
|
.danger {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
@media only screen and (max-width: 900px) {
|
@media only screen and (max-width: 900px) {
|
||||||
#main {
|
#main {
|
||||||
grid-template-columns: auto;
|
grid-template-columns: auto;
|
||||||
@@ -67,6 +70,8 @@
|
|||||||
<br>
|
<br>
|
||||||
<button onclick="issue()">Issue domain</button>
|
<button onclick="issue()">Issue domain</button>
|
||||||
<a id="issue-link"></a>
|
<a id="issue-link"></a>
|
||||||
|
<br><br>
|
||||||
|
<button class="danger" onclick="freeze(true)">Freeze TLD</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="domain">
|
<div id="domain">
|
||||||
<h2>Domain Account Manager</h2>
|
<h2>Domain Account Manager</h2>
|
||||||
@@ -104,8 +109,8 @@
|
|||||||
<br>
|
<br>
|
||||||
<button onclick="transfer()">Transfer domain</button>
|
<button onclick="transfer()">Transfer domain</button>
|
||||||
<a id="transfer-link"></a>
|
<a id="transfer-link"></a>
|
||||||
<h3>Upload metadata to IPFS</h3>
|
<br><br>
|
||||||
//
|
<button class="danger" onclick="freeze(false)">Freeze domain</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="resolver">
|
<div id="resolver">
|
||||||
@@ -279,11 +284,16 @@
|
|||||||
|
|
||||||
async function get_domain_account_domain() {
|
async function get_domain_account_domain() {
|
||||||
const resolver = new bns.Resolver(rpc2, tld_mapping);
|
const resolver = new bns.Resolver(rpc2, tld_mapping);
|
||||||
domain_account_domain = resolver.resolve_backwards_ish(wallet.address, d.g("rc-tld").value);
|
domain_account_domain = await resolver.resolve_backwards_ish(wallet.address, d.g("rc-tld").value);
|
||||||
domain_account_domain = await domain_account_domain;
|
let frozen = false;
|
||||||
|
if (domain_account_domain.history[domain_account_domain.history.length - 1].type === "freeze") {
|
||||||
|
alert("This domain is frozen! That means you can't do anything with it.");
|
||||||
|
frozen = true;
|
||||||
|
}
|
||||||
const { name, resolved_address, metadata_hash } = domain_account_domain;
|
const { name, resolved_address, metadata_hash } = domain_account_domain;
|
||||||
console.log(domain_account_domain);
|
console.log(domain_account_domain);
|
||||||
d.g("found-name").textContent = name
|
d.g("found-name").textContent = name;
|
||||||
|
if (frozen) d.g("found-name").classList.add("danger");
|
||||||
d.g("found-address").textContent = resolved_address;
|
d.g("found-address").textContent = resolved_address;
|
||||||
const cid_v0 = metadata_hash ? get_cid_v0_from_public_key(metadata_hash) : "none";
|
const cid_v0 = metadata_hash ? get_cid_v0_from_public_key(metadata_hash) : "none";
|
||||||
d.g("found-metadata").innerHTML = `${metadata_hash} (IPFS translation: <a href="https://ipfs.oversas.org/ipfs/${cid_v0}" target="_blank">${cid_v0}</a>)`;
|
d.g("found-metadata").innerHTML = `${metadata_hash} (IPFS translation: <a href="https://ipfs.oversas.org/ipfs/${cid_v0}" target="_blank">${cid_v0}</a>)`;
|
||||||
@@ -308,6 +318,13 @@
|
|||||||
d.g("transfer-link").href = `https://creeper.banano.cc/hash/${transfer_hash}`;
|
d.g("transfer-link").href = `https://creeper.banano.cc/hash/${transfer_hash}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function freeze(is_tld) {
|
||||||
|
if (await prompt(`Are you sure you want to freeze the ${ is_tld ? "TLD" : "domain" }? This will mean you can no longer transfer it, change the resolved address, or the metadata hash. Respond 'I am super sure' to proceed.`).trim() === "I am super sure") {
|
||||||
|
is_tld ? await tld_account.freeze() : await domain_account.freeze();
|
||||||
|
alert(`The ${ is_tld ? "TLD" : "domain" } should now be frozen`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function seed_proceed() {
|
function seed_proceed() {
|
||||||
d.g("start-2").style.display = "none";
|
d.g("start-2").style.display = "none";
|
||||||
d.g("main").style.display = "grid";
|
d.g("main").style.display = "grid";
|
||||||
|
|||||||
8
constants.ts
Normal file
8
constants.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { whole_to_raw, get_address_from_public_key } from "banani";
|
||||||
|
|
||||||
|
export const TRANS_MIN = whole_to_raw("0.0012070301");
|
||||||
|
export const TRANS_MAX = whole_to_raw("0.00120703011");
|
||||||
|
|
||||||
|
export const FREEZE_PUB_KEY = "451" + "1".repeat(61);
|
||||||
|
export const FREEZE_REP = get_address_from_public_key(FREEZE_PUB_KEY);
|
||||||
|
|
||||||
@@ -1 +1 @@
|
|||||||
window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA62ZXU/bMBSG/0uv2RcbjHEHTNvQ2IYAiQuEolPntLGaOpXtFKpp/31O0zZO7TiuncvW73mf468TO3n6O5L4KkfnozEwYHR0NFqAzNTveZGWOYp39f9vMznPVeOMsnR0/uloRHIQQsmkSN9Q8UZ5IGdQSUhG85QjG50/7cxvOV2CxJ+4uiCkKJlsOGujhmMo2+QPx2fd7H9HO+Dd7VUnQrUFmz5SmV0CmZULl32jCgcVfHbLiyVNkTtRmi4M9gh5jt0TUjeHWW+m8BJyYARbc0KZkk+ANCBD3GYen5wewvxBhSz46jIvyMyDqsuH4Pr1tREPwoSXA7u7jRiIflin1/oo8jWbFH7MjTKKdocEVW0a554LuaUfiHxflNx3I1miBsriIeMosiJPD01ED4zMZaGckEmQdOk9HnsxURk8Ip1m0o+800YRxaYyCj+oLo/jtgfOF29GhWXRW9IiKtg69Gq9ONydagkjWB4VS9dFkH4X93TKQJYce2maNoIofDsn4nvXtwh3ojDGV8xxCuopJXwWh6mOpXoDg1kq8Hrr60LpukBSuw78YTllfRW7K2bADLzqtztykGwOyyCYar9OmLzu64T3UyNVlz8l2kHkaqE9HerWPev3Xz5/ODk+xP6W44S+uiG1Jhy1LiIXef5QeXegWppI1CUISnphjSoS9wNE5gJV7ZGIG1WmyKq3S5osEniv9gleZcCm2Evd18aiy3HFcBJrSTjoUZ2duwjrtghrtfG/lYxIWrAugiYJB41B4MfjRBZJqcrPGXAOqwY42fjvoDZ5G37qeBulcYkylbwkMpmr2gBTTMbVnCTA0iRrbQUjh77QoHymKBOoC1Uy4cU8WZTjnJJkhq7hcEQFZ7GoX7lVHrWnQEx7crDGhGew60RtBvvPEHsO9qjBstD6eGAmWmRQNtWiqteYA9yIwhj46r0JDW0QUUV7Ew1tEJHDS+Xy0i6bBkyXBXGEuj5takJPKdlThtM2lagPtZEFcZrBr0anLsQOnk0+AFetPW+o0oYR5eTMe2ma4iDmEjmdrPxWjaGNIVbrAlOPBWTVB5HXO6saM7XTHEBddgDnWb9DF3OgrPMjU6vZ+KbR5fNLpTe1fYaxqVyudyiKfGlz2ra4oh9uvnZ2rGnzc+jskiHpHyXrfbJuMq6QRnD36z2tvd/mF0pIQYLDaSvpN6tfWNvfi7QUPlb7M27xsk29zeyBAxMTp9lW4jnwxgVJb7Oe8TWfmz/fm/AlcFq94hfv1N/tyI960PbwqnY5oWmyfG+rB4Zovxrs3SdOzpxPCk3gMqJTvxOKReewrTtQyR2nWkPkMEyRFCkm6XqmEgZzaw03VQ5LZD6WpsphuTky1oNvc2sJDKPn/7j8/9qZIAAA"
|
window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA62ZYXPaOBCG/wuf02ubXnq5fAspuWaapAzhJu11Oh4hL1iDkRlJJqE3999PxgbLSJaF5I/Jvvs+K3m9RvaPfwcCXsXgajBDFFEyOBuskUjk36sszlPgb8v//5aIVSqDS0LjwdXvZwOcIs6lTPD4DeFvpAcwigoJTkgaM6CDqx8H8zEjGyTgC2yvMc5yKmrOzqjmaMom+f35ZTv7v7MDcDK+aUXImLfpMxHJEOFlvrbZ1yp/UMaWY5ZtSAzMilJ0frBnlKbQfkHKsJ91dQmHKEUUQ+OaECrlc4RrkCZuMs8vPp7C/Ey4yNh2mGZ46UBV5X1w3dZai3thopcTl7vP6Il+2qJ3+iDyHZ1nbsxKGUSbAAY5m2apYyM39D2Rn7Kcud5IhqyeqpgmDHiSpfGphaiJgbWspRNQgQTZOO/HUU5QBc9AFolwIx+0QUReTUbuBlXlYdzmxrni9Sy/KjpHWsAE26Xe7JrDvqiGMIDlMLFUXQDpMXsiC4pEzqCTpmgDiNx1cTx8dV1NeBD5MT5BCgskn1LcpTl0dSjVGejNkol3e18bStV5kppz4CtNCe2a2G05PVbgNL/tmb1Uc1oF3lTzcULntR8nnJ8asTz8SdEBIrZr5elQRo+s3/35x/uL81Psxwzm5NUOKTX+qN0QuU7TaeHdgmpoAlFDxAnuhNWqQNxnxBMbqIgHIu7lmMLbziUpskDgk7xP4CZBdAGd1GNtKDqfFQwrsZT4g57lb+c2wi4WYC1v/NucYkEy2kZQJP6gGeLw4TwSWZTL8XOJGEPbGjiv/A9Qk7wJ/2h5G6VwsTQVLMciWsnZgBYQzYprEiEaR0njVtBq6Er1qmcBIkLloIrmLFtF63yWEhwtwbYdlizvKtblK7fCo/TkAHFHDcYc/woOiyjN0PEzxFyDOau3KpQ1nliJkulVTdFUZY9ZwLXIjwGvzjehpvUiymxnoqb1IjL0Uri8NMemBlNlXhwuj0/VTOgYJUdKf1o1ibpQlcyLU29+sTvlILbwTPIeuLL3nKFS60cU80vn1tTFXswNMDLfunWNpg0hFn0BsUMDGfVe5N2dVeyZvNMsQFV2AueneobOVojQ1o9MjbD2TaPN50GWtzB9hjGpbK4T4Fm6MTntI7bs6f2n1oXVMTeH1iVpku5dMp4ny5B2hNSS21/vKfFum1sG8Mv8JkMVdBs9gEAxEshitZd0m5Vvvm1lVQoXq+PWMXiZeshkNmWI8rnVbC9xvILaSUuNGQ8Lis/tZDT6ZxSN/x5GX0bfa6cNYqT4bMDfNhVNvw8Gq8lobLGRUYvF/de/TLny35ak6eT68Sl6uP5mSj0Euw3uHi0Gd48Wg/2pQI5PTOJo8840aDXR8Zg9OqhdXFofwYrAZkQWbj/9DDqLbbmAQm45Lmgii2EMOIshinedG1G0Mj4cdZXFEqiLpa6yWFa/xcvNN7k1BJrRz/8Bki4U8PIhAAA="
|
||||||
@@ -1 +1 @@
|
|||||||
window.searchData = "data:application/octet-stream;base64,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";
|
window.searchData = "data:application/octet-stream;base64,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";
|
||||||
File diff suppressed because one or more lines are too long
@@ -12,6 +12,9 @@
|
|||||||
#main div {
|
#main div {
|
||||||
max-width: 50vw;
|
max-width: 50vw;
|
||||||
}
|
}
|
||||||
|
.danger {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
@media only screen and (max-width: 900px) {
|
@media only screen and (max-width: 900px) {
|
||||||
#main {
|
#main {
|
||||||
grid-template-columns: auto;
|
grid-template-columns: auto;
|
||||||
@@ -67,6 +70,8 @@
|
|||||||
<br>
|
<br>
|
||||||
<button onclick="issue()">Issue domain</button>
|
<button onclick="issue()">Issue domain</button>
|
||||||
<a id="issue-link"></a>
|
<a id="issue-link"></a>
|
||||||
|
<br><br>
|
||||||
|
<button class="danger" onclick="freeze(true)">Freeze TLD</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="domain">
|
<div id="domain">
|
||||||
<h2>Domain Account Manager</h2>
|
<h2>Domain Account Manager</h2>
|
||||||
@@ -104,8 +109,8 @@
|
|||||||
<br>
|
<br>
|
||||||
<button onclick="transfer()">Transfer domain</button>
|
<button onclick="transfer()">Transfer domain</button>
|
||||||
<a id="transfer-link"></a>
|
<a id="transfer-link"></a>
|
||||||
<h3>Upload metadata to IPFS</h3>
|
<br><br>
|
||||||
//
|
<button class="danger" onclick="freeze(false)">Freeze domain</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="resolver">
|
<div id="resolver">
|
||||||
@@ -279,11 +284,16 @@
|
|||||||
|
|
||||||
async function get_domain_account_domain() {
|
async function get_domain_account_domain() {
|
||||||
const resolver = new bns.Resolver(rpc2, tld_mapping);
|
const resolver = new bns.Resolver(rpc2, tld_mapping);
|
||||||
domain_account_domain = resolver.resolve_backwards_ish(wallet.address, d.g("rc-tld").value);
|
domain_account_domain = await resolver.resolve_backwards_ish(wallet.address, d.g("rc-tld").value);
|
||||||
domain_account_domain = await domain_account_domain;
|
let frozen = false;
|
||||||
|
if (domain_account_domain.history[domain_account_domain.history.length - 1].type === "freeze") {
|
||||||
|
alert("This domain is frozen! That means you can't do anything with it.");
|
||||||
|
frozen = true;
|
||||||
|
}
|
||||||
const { name, resolved_address, metadata_hash } = domain_account_domain;
|
const { name, resolved_address, metadata_hash } = domain_account_domain;
|
||||||
console.log(domain_account_domain);
|
console.log(domain_account_domain);
|
||||||
d.g("found-name").textContent = name
|
d.g("found-name").textContent = name;
|
||||||
|
if (frozen) d.g("found-name").classList.add("danger");
|
||||||
d.g("found-address").textContent = resolved_address;
|
d.g("found-address").textContent = resolved_address;
|
||||||
const cid_v0 = metadata_hash ? get_cid_v0_from_public_key(metadata_hash) : "none";
|
const cid_v0 = metadata_hash ? get_cid_v0_from_public_key(metadata_hash) : "none";
|
||||||
d.g("found-metadata").innerHTML = `${metadata_hash} (IPFS translation: <a href="https://ipfs.oversas.org/ipfs/${cid_v0}" target="_blank">${cid_v0}</a>)`;
|
d.g("found-metadata").innerHTML = `${metadata_hash} (IPFS translation: <a href="https://ipfs.oversas.org/ipfs/${cid_v0}" target="_blank">${cid_v0}</a>)`;
|
||||||
@@ -308,6 +318,13 @@
|
|||||||
d.g("transfer-link").href = `https://creeper.banano.cc/hash/${transfer_hash}`;
|
d.g("transfer-link").href = `https://creeper.banano.cc/hash/${transfer_hash}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function freeze(is_tld) {
|
||||||
|
if (await prompt(`Are you sure you want to freeze the ${ is_tld ? "TLD" : "domain" }? This will mean you can no longer transfer it, change the resolved address, or the metadata hash. Respond 'I am super sure' to proceed.`).trim() === "I am super sure") {
|
||||||
|
is_tld ? await tld_account.freeze() : await domain_account.freeze();
|
||||||
|
alert(`The ${ is_tld ? "TLD" : "domain" } should now be frozen`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function seed_proceed() {
|
function seed_proceed() {
|
||||||
d.g("start-2").style.display = "none";
|
d.g("start-2").style.display = "none";
|
||||||
d.g("main").style.display = "grid";
|
d.g("main").style.display = "grid";
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
docs/interfaces/DomainFreeze.html
Normal file
3
docs/interfaces/DomainFreeze.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -6,12 +6,17 @@
|
|||||||
<a href="classes/TLDAccountManager.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-128"></use></svg><span>TLDAccount<wbr/>Manager</span></a>
|
<a href="classes/TLDAccountManager.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-128"></use></svg><span>TLDAccount<wbr/>Manager</span></a>
|
||||||
</div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Interfaces</h3><div class="tsd-index-list"><a href="interfaces/Domain.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain</span></a>
|
</div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Interfaces</h3><div class="tsd-index-list"><a href="interfaces/Domain.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain</span></a>
|
||||||
<a href="interfaces/DomainBlock.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain<wbr/>Block</span></a>
|
<a href="interfaces/DomainBlock.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain<wbr/>Block</span></a>
|
||||||
|
<a href="interfaces/DomainFreeze.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain<wbr/>Freeze</span></a>
|
||||||
<a href="interfaces/DomainMetadata.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain<wbr/>Metadata</span></a>
|
<a href="interfaces/DomainMetadata.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain<wbr/>Metadata</span></a>
|
||||||
<a href="interfaces/DomainReceive.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain<wbr/>Receive</span></a>
|
<a href="interfaces/DomainReceive.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain<wbr/>Receive</span></a>
|
||||||
<a href="interfaces/DomainResolver.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain<wbr/>Resolver</span></a>
|
<a href="interfaces/DomainResolver.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain<wbr/>Resolver</span></a>
|
||||||
<a href="interfaces/DomainTransfer.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain<wbr/>Transfer</span></a>
|
<a href="interfaces/DomainTransfer.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Domain<wbr/>Transfer</span></a>
|
||||||
</div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Type Aliases</h3><div class="tsd-index-list"><a href="types/DomainBlocks.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-2097152"></use></svg><span>Domain<wbr/>Blocks</span></a>
|
</div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Type Aliases</h3><div class="tsd-index-list"><a href="types/DomainBlocks.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-2097152"></use></svg><span>Domain<wbr/>Blocks</span></a>
|
||||||
</div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Variables</h3><div class="tsd-index-list"><a href="variables/LOG.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-32"></use></svg><span>LOG</span></a>
|
</div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Variables</h3><div class="tsd-index-list"><a href="variables/FREEZE_PUB_KEY.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-32"></use></svg><span>FREEZE_<wbr/>PUB_<wbr/>KEY</span></a>
|
||||||
|
<a href="variables/FREEZE_REP.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-32"></use></svg><span>FREEZE_<wbr/>REP</span></a>
|
||||||
|
<a href="variables/LOG.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-32"></use></svg><span>LOG</span></a>
|
||||||
|
<a href="variables/TRANS_MAX.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-32"></use></svg><span>TRANS_<wbr/>MAX</span></a>
|
||||||
|
<a href="variables/TRANS_MIN.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-32"></use></svg><span>TRANS_<wbr/>MIN</span></a>
|
||||||
</div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Functions</h3><div class="tsd-index-list"><a href="functions/address_to_cid_v0.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-64"></use></svg><span>address_<wbr/>to_<wbr/>cid_<wbr/>v0</span></a>
|
</div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Functions</h3><div class="tsd-index-list"><a href="functions/address_to_cid_v0.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-64"></use></svg><span>address_<wbr/>to_<wbr/>cid_<wbr/>v0</span></a>
|
||||||
<a href="functions/base58_to_hex.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-64"></use></svg><span>base58_<wbr/>to_<wbr/>hex</span></a>
|
<a href="functions/base58_to_hex.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-64"></use></svg><span>base58_<wbr/>to_<wbr/>hex</span></a>
|
||||||
<a href="functions/bigint_to_uint8array.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-64"></use></svg><span>bigint_<wbr/>to_<wbr/>uint8array</span></a>
|
<a href="functions/bigint_to_uint8array.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-64"></use></svg><span>bigint_<wbr/>to_<wbr/>uint8array</span></a>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
1
docs/variables/FREEZE_PUB_KEY.html
Normal file
1
docs/variables/FREEZE_PUB_KEY.html
Normal file
File diff suppressed because one or more lines are too long
1
docs/variables/FREEZE_REP.html
Normal file
1
docs/variables/FREEZE_REP.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
docs/variables/TRANS_MAX.html
Normal file
1
docs/variables/TRANS_MAX.html
Normal file
File diff suppressed because one or more lines are too long
1
docs/variables/TRANS_MIN.html
Normal file
1
docs/variables/TRANS_MIN.html
Normal file
File diff suppressed because one or more lines are too long
1
main.ts
1
main.ts
@@ -1,4 +1,5 @@
|
|||||||
export * from "./util";
|
export * from "./util";
|
||||||
|
export * from "./constants";
|
||||||
export * from "./resolver";
|
export * from "./resolver";
|
||||||
export * from "./manager";
|
export * from "./manager";
|
||||||
export * from "./types";
|
export * from "./types";
|
||||||
|
|||||||
26
manager.ts
26
manager.ts
@@ -4,6 +4,7 @@ import { get_address_from_public_key, raw_to_whole, whole_to_raw, Wallet } from
|
|||||||
import type { Domain } from "./types";
|
import type { Domain } from "./types";
|
||||||
import { DomainAccount, TLDAccount } from "./resolver";
|
import { DomainAccount, TLDAccount } from "./resolver";
|
||||||
import { decode_domain_name, encode_domain_name, LOG } from "./util";
|
import { decode_domain_name, encode_domain_name, LOG } from "./util";
|
||||||
|
import { TRANS_MAX, TRANS_MIN, FREEZE_REP, FREEZE_PUB_KEY } from "./constants";
|
||||||
|
|
||||||
export class TLDAccountManager extends TLDAccount {
|
export class TLDAccountManager extends TLDAccount {
|
||||||
wallet: Wallet;
|
wallet: Wallet;
|
||||||
@@ -22,6 +23,11 @@ export class TLDAccountManager extends TLDAccount {
|
|||||||
return block_hash;
|
return block_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async freeze() {
|
||||||
|
await this.wallet.change_representative(FREEZE_REP);
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
//ideally tld starts out with say, 100 Banano to open with, and never needs to receive anything ever again. 100 Banano is over for over 80k domain issuances.
|
//ideally tld starts out with say, 100 Banano to open with, and never needs to receive anything ever again. 100 Banano is over for over 80k domain issuances.
|
||||||
async receive() {
|
async receive() {
|
||||||
//up to 20, technically
|
//up to 20, technically
|
||||||
@@ -39,7 +45,7 @@ export class DomainAccountManager extends DomainAccount {
|
|||||||
this.domain = domain;
|
this.domain = domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
async receive_domain(receive_hash: string, allow_burning?: boolean) {
|
async receive_domain(receive_hash: string, tld?: Address, allow_burning?: boolean) {
|
||||||
let burning = false;
|
let burning = false;
|
||||||
const { history } = await this.rpc.get_account_history(this.address, 1);
|
const { history } = await this.rpc.get_account_history(this.address, 1);
|
||||||
if (history.length > 1 && !allow_burning) {
|
if (history.length > 1 && !allow_burning) {
|
||||||
@@ -47,26 +53,23 @@ export class DomainAccountManager extends DomainAccount {
|
|||||||
throw new Error("`allow_burning` must be true in order to receive this domain");
|
throw new Error("`allow_burning` must be true in order to receive this domain");
|
||||||
}
|
}
|
||||||
const block_info = await this.rpc.get_block_info(receive_hash);
|
const block_info = await this.rpc.get_block_info(receive_hash);
|
||||||
const min = whole_to_raw("0.0012070301");
|
|
||||||
const max = whole_to_raw("0.00120703011");
|
|
||||||
const amount = BigInt(block_info.amount);
|
const amount = BigInt(block_info.amount);
|
||||||
if (amount < min || amount > max) throw new Error("`receive_hash` is not a Domain Transfer block");
|
if (amount < TRANS_MIN || amount > TRANS_MAX) throw new Error("`receive_hash` is not a Domain Transfer block");
|
||||||
await this.wallet.receive(receive_hash);
|
await this.wallet.receive(receive_hash, undefined, tld);
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
async transfer_domain(domain_name: string, to: Address): Promise<string> {
|
async transfer_domain(domain_name: string, to: Address): Promise<string> {
|
||||||
const balance = (await this.wallet.get_account_info()).balance;
|
const balance = (await this.wallet.get_account_info()).balance;
|
||||||
const min = whole_to_raw("0.0012070301");
|
let send_amount = raw_to_whole(TRANS_MAX);
|
||||||
const max = whole_to_raw("0.00120703011");
|
if (TRANS_MAX > BigInt(balance) && TRANS_MIN <= BigInt(balance)) send_amount = raw_to_whole(BigInt(balance));
|
||||||
let send_amount = raw_to_whole(max);
|
|
||||||
if (max > BigInt(balance) && min <= BigInt(balance)) send_amount = raw_to_whole(BigInt(balance));
|
|
||||||
const block_hash = await this.wallet.send(to, send_amount, undefined, get_address_from_public_key(encode_domain_name(domain_name)));
|
const block_hash = await this.wallet.send(to, send_amount, undefined, get_address_from_public_key(encode_domain_name(domain_name)));
|
||||||
//
|
//
|
||||||
return block_hash;
|
return block_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
async declare_domain_metadata(metadata_hash: string) {
|
async declare_domain_metadata(metadata_hash: string) {
|
||||||
|
if (metadata_hash === FREEZE_PUB_KEY) throw new Error("A metadata hash of all 1s freezes the domain");
|
||||||
await this.wallet.change_representative(get_address_from_public_key(metadata_hash));
|
await this.wallet.change_representative(get_address_from_public_key(metadata_hash));
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
@@ -75,5 +78,10 @@ export class DomainAccountManager extends DomainAccount {
|
|||||||
await this.wallet.send(address, raw_to_whole(4224n));
|
await this.wallet.send(address, raw_to_whole(4224n));
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async freeze() {
|
||||||
|
await this.wallet.change_representative(FREEZE_REP);
|
||||||
|
//
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import * as crypto from "crypto";
|
|||||||
|
|
||||||
let tld_wallet = new bns.banani.Wallet(rpc, test_seed);
|
let tld_wallet = new bns.banani.Wallet(rpc, test_seed);
|
||||||
|
|
||||||
|
console.log(await new bns.Resolver(rpc2, { "test": tld_wallet.address }).resolve("chicken", "test")); //freeze test
|
||||||
|
|
||||||
console.log(await new bns.Resolver(rpc2, { "test": tld_wallet.address }).resolve_backwards_ish("ban_1119d44eg3fey3mxpk8mshn7gf5dfzsuiaz1ypoh5nqy8bxbao54zzc5rnka", "test"));
|
console.log(await new bns.Resolver(rpc2, { "test": tld_wallet.address }).resolve_backwards_ish("ban_1119d44eg3fey3mxpk8mshn7gf5dfzsuiaz1ypoh5nqy8bxbao54zzc5rnka", "test"));
|
||||||
|
|
||||||
let tld = new bns.TLDAccountManager(rpc, tld_wallet);
|
let tld = new bns.TLDAccountManager(rpc, tld_wallet);
|
||||||
@@ -21,7 +23,7 @@ import * as crypto from "crypto";
|
|||||||
|
|
||||||
const rand_wallet = bns.banani.Wallet.gen_random_wallet(rpc);
|
const rand_wallet = bns.banani.Wallet.gen_random_wallet(rpc);
|
||||||
|
|
||||||
const rand_name = `test${String(Math.random()).replaceAll(".", "")}`;
|
const rand_name = `rc-test${String(Math.random()).replaceAll(".", "")}`;
|
||||||
|
|
||||||
const issue_hash = await tld.issue_domain_name(rand_name, rand_wallet.address);
|
const issue_hash = await tld.issue_domain_name(rand_name, rand_wallet.address);
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ import * as crypto from "crypto";
|
|||||||
|
|
||||||
await rand_dam.declare_domain_resolve_to("ban_3346kkobb11qqpo17imgiybmwrgibr7yi34mwn5j6uywyke8f7fnfp94uyps");
|
await rand_dam.declare_domain_resolve_to("ban_3346kkobb11qqpo17imgiybmwrgibr7yi34mwn5j6uywyke8f7fnfp94uyps");
|
||||||
|
|
||||||
await rand_dam.declare_domain_metadata("1".repeat(64));
|
await rand_dam.declare_domain_metadata("6".repeat(64));
|
||||||
|
|
||||||
await rand_dam.declare_domain_resolve_to("ban_1burnbabyburndiscoinferno111111111111111111111111111aj49sw3w");
|
await rand_dam.declare_domain_resolve_to("ban_1burnbabyburndiscoinferno111111111111111111111111111aj49sw3w");
|
||||||
|
|
||||||
@@ -43,7 +45,25 @@ import * as crypto from "crypto";
|
|||||||
|
|
||||||
await rand_dam2.receive_domain(transfer_hash);
|
await rand_dam2.receive_domain(transfer_hash);
|
||||||
|
|
||||||
await rand_dam2.declare_domain_metadata("0".repeat(64));
|
await rand_dam2.declare_domain_metadata("2".repeat(64));
|
||||||
|
|
||||||
|
/*
|
||||||
|
//freeze test
|
||||||
|
await rand_dam2.freeze();
|
||||||
|
|
||||||
|
const rand_wallet3 = bns.banani.Wallet.gen_random_wallet(rpc);
|
||||||
|
console.log(rand_wallet3.seed);
|
||||||
|
|
||||||
|
const transfer_hash2 = await rand_dam2.transfer_domain(rand_name, rand_wallet3.address);
|
||||||
|
|
||||||
|
const rand_dam3 = new bns.DomainAccountManager(rpc, rand_wallet3);
|
||||||
|
|
||||||
|
await rand_dam3.receive_domain(transfer_hash2);
|
||||||
|
|
||||||
|
await rand_dam3.declare_domain_metadata("4".repeat(64));
|
||||||
|
|
||||||
|
await rand_dam3.declare_domain_resolve_to("ban_3fzpw7pb9xt64qhwi47oa47x9zj713fkshntdk5y7khmn54n18szb7ymybdt");
|
||||||
|
*/
|
||||||
|
|
||||||
//await rand_dam2.declare_domain_resolve_to("ban_1o7ija3mdbmpzt8qfnck583tn99fiupgbyzxtbk5h4g6j57a7rawge6yzxqp");
|
//await rand_dam2.declare_domain_resolve_to("ban_1o7ija3mdbmpzt8qfnck583tn99fiupgbyzxtbk5h4g6j57a7rawge6yzxqp");
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "banani-bns",
|
"name": "banani-bns",
|
||||||
"version": "0.0.2",
|
"version": "0.0.3",
|
||||||
"description": "JS/TS library for the Banano cryptocurrency's currently unofficial Banano Name System (BNS)",
|
"description": "JS/TS library for the Banano cryptocurrency's currently unofficial Banano Name System (BNS)",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
37
resolver.ts
37
resolver.ts
@@ -1,10 +1,9 @@
|
|||||||
import type { RPC } from "banani";
|
import type { Address, AccountHistoryRawRPC, RPC } from "banani";
|
||||||
import { get_address_from_public_key, get_public_key_from_address, whole_to_raw } from "banani";
|
import { get_address_from_public_key, get_public_key_from_address, whole_to_raw } from "banani";
|
||||||
|
|
||||||
import type { Address, AccountHistoryRawRPC } from "banani";
|
|
||||||
|
|
||||||
import type { Domain, DomainTransfer } from "./types";
|
import type { Domain, DomainTransfer } from "./types";
|
||||||
import { decode_domain_name, encode_domain_name, LOG } from "./util";
|
import { decode_domain_name, encode_domain_name, LOG } from "./util";
|
||||||
|
import { FREEZE_REP, TRANS_MAX, TRANS_MIN } from "./constants";
|
||||||
|
|
||||||
class Account {
|
class Account {
|
||||||
readonly rpc: RPC;
|
readonly rpc: RPC;
|
||||||
@@ -27,6 +26,8 @@ class Account {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export class TLDAccount extends Account {
|
export class TLDAccount extends Account {
|
||||||
all_issued: Domain[];
|
all_issued: Domain[];
|
||||||
|
|
||||||
@@ -42,9 +43,7 @@ export class TLDAccount extends Account {
|
|||||||
const { history } = await this.get_history_from_open(head_hash, 100);
|
const { history } = await this.get_history_from_open(head_hash, 100);
|
||||||
for (const block of history) {
|
for (const block of history) {
|
||||||
const amount = BigInt(block.amount ?? 0); //no amount if is change rep only
|
const amount = BigInt(block.amount ?? 0); //no amount if is change rep only
|
||||||
const min = whole_to_raw("0.0012070301");
|
if (block.subtype === "send" && amount >= TRANS_MIN && amount <= TRANS_MAX) {
|
||||||
const max = whole_to_raw("0.00120703011");
|
|
||||||
if (amount >= min && amount <= max) {
|
|
||||||
const found_name = decode_domain_name(get_public_key_from_address(block.representative));
|
const found_name = decode_domain_name(get_public_key_from_address(block.representative));
|
||||||
//if already in issued, this one is invalid
|
//if already in issued, this one is invalid
|
||||||
if (name === found_name) {
|
if (name === found_name) {
|
||||||
@@ -61,7 +60,8 @@ export class TLDAccount extends Account {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (block.hash === frontier_hash) {
|
//again, no else if because of block.hash === frontier_hash
|
||||||
|
if ((block.representative === FREEZE_REP && block.subtype === "change") || (block.hash === frontier_hash)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,9 +77,7 @@ export class TLDAccount extends Account {
|
|||||||
const { history } = await this.get_history_from_open(head_hash, 100);
|
const { history } = await this.get_history_from_open(head_hash, 100);
|
||||||
for (const block of history) {
|
for (const block of history) {
|
||||||
const amount = BigInt(block.amount ?? 0); //no amount if change rep only
|
const amount = BigInt(block.amount ?? 0); //no amount if change rep only
|
||||||
const min = whole_to_raw("0.0012070301");
|
if (block.subtype === "send" && amount >= TRANS_MIN && amount <= TRANS_MAX) {
|
||||||
const max = whole_to_raw("0.00120703011");
|
|
||||||
if (block.subtype === "send" && amount >= min && amount <= max) {
|
|
||||||
const name = decode_domain_name(get_public_key_from_address(block.representative));
|
const name = decode_domain_name(get_public_key_from_address(block.representative));
|
||||||
//if already in issued, this one is invalid
|
//if already in issued, this one is invalid
|
||||||
if (!issued[name]) {
|
if (!issued[name]) {
|
||||||
@@ -97,12 +95,13 @@ export class TLDAccount extends Account {
|
|||||||
} else if (LOG) {
|
} else if (LOG) {
|
||||||
console.log(`"${name}" already issued but TLD tried to issue again. Invalid.`);
|
console.log(`"${name}" already issued but TLD tried to issue again. Invalid.`);
|
||||||
}
|
}
|
||||||
if (block.hash === frontier_hash) {
|
}
|
||||||
|
//cannot be "else if" because of the block.hash === frontier_hash thing
|
||||||
|
if ((block.representative === FREEZE_REP && block.subtype === "change") || (block.hash === frontier_hash)) {
|
||||||
this.all_issued = Object.values(issued);
|
this.all_issued = Object.values(issued);
|
||||||
return this.all_issued;
|
return this.all_issued;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
head_hash = history[history.length - 1].hash;
|
head_hash = history[history.length - 1].hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,8 +130,6 @@ export class DomainAccount extends Account {
|
|||||||
const { history } = await this.get_history_from_open(head_hash, 1000) as AccountHistoryRawRPC;
|
const { history } = await this.get_history_from_open(head_hash, 1000) as AccountHistoryRawRPC;
|
||||||
for (const block of history) {
|
for (const block of history) {
|
||||||
const amount = BigInt(block.amount ?? 0); //amount is 0 if change rep only, apparently
|
const amount = BigInt(block.amount ?? 0); //amount is 0 if change rep only, apparently
|
||||||
const min = whole_to_raw("0.0012070301");
|
|
||||||
const max = whole_to_raw("0.00120703011");
|
|
||||||
if (block.height === "1") {
|
if (block.height === "1") {
|
||||||
//domain burned due to not being received as the opening block
|
//domain burned due to not being received as the opening block
|
||||||
//? is in case fake domain
|
//? is in case fake domain
|
||||||
@@ -146,7 +143,7 @@ export class DomainAccount extends Account {
|
|||||||
type: "receive",
|
type: "receive",
|
||||||
block,
|
block,
|
||||||
});
|
});
|
||||||
} else if (block.subtype === "send" && amount >= min && amount <= max) {
|
} else if (block.subtype === "send" && amount >= TRANS_MIN && amount <= TRANS_MAX) {
|
||||||
const name = decode_domain_name(get_public_key_from_address(block.representative));
|
const name = decode_domain_name(get_public_key_from_address(block.representative));
|
||||||
if (this.domain.name === name) {
|
if (this.domain.name === name) {
|
||||||
//domain is transferred away, this domain account no longer owns it
|
//domain is transferred away, this domain account no longer owns it
|
||||||
@@ -160,6 +157,12 @@ export class DomainAccount extends Account {
|
|||||||
});
|
});
|
||||||
return this.domain;
|
return this.domain;
|
||||||
}
|
}
|
||||||
|
} else if (block.subtype === "change" && block.representative === FREEZE_REP) {
|
||||||
|
this.domain.history.push({
|
||||||
|
type: "freeze",
|
||||||
|
block,
|
||||||
|
});
|
||||||
|
return this.domain;
|
||||||
} else if (block.subtype === "change") {
|
} else if (block.subtype === "change") {
|
||||||
this.domain.metadata_hash = get_public_key_from_address(block.representative);
|
this.domain.metadata_hash = get_public_key_from_address(block.representative);
|
||||||
this.domain.history.push({
|
this.domain.history.push({
|
||||||
@@ -167,7 +170,6 @@ export class DomainAccount extends Account {
|
|||||||
block,
|
block,
|
||||||
metadata_hash: this.domain.metadata_hash,
|
metadata_hash: this.domain.metadata_hash,
|
||||||
});
|
});
|
||||||
//
|
|
||||||
} else if (block.subtype === "send" && amount === 4224n) {
|
} else if (block.subtype === "send" && amount === 4224n) {
|
||||||
this.domain.resolved_address = get_address_from_public_key(block.link);
|
this.domain.resolved_address = get_address_from_public_key(block.link);
|
||||||
this.domain.history.push({
|
this.domain.history.push({
|
||||||
@@ -214,7 +216,8 @@ export class Resolver {
|
|||||||
const transfer_block = await this.rpc.get_block_info(transfer_hash);
|
const transfer_block = await this.rpc.get_block_info(transfer_hash);
|
||||||
const domain_name = decode_domain_name(get_public_key_from_address(transfer_block.contents.representative));
|
const domain_name = decode_domain_name(get_public_key_from_address(transfer_block.contents.representative));
|
||||||
let domain = await this.resolve(domain_name, tld);
|
let domain = await this.resolve(domain_name, tld);
|
||||||
const last_transfer = domain.history.reverse().find((b): b is DomainTransfer => b.type === "transfer");
|
//.reverse() mutates the original array, evil bastards!
|
||||||
|
const last_transfer = domain?.history.slice().reverse().find((b): b is DomainTransfer => b.type === "transfer");
|
||||||
if (last_transfer.to === domain_account_address) return domain;
|
if (last_transfer.to === domain_account_address) return domain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
types.ts
8
types.ts
@@ -1,7 +1,7 @@
|
|||||||
import type { Address, AccountHistoryRawBlock } from "banani";
|
import type { Address, AccountHistoryRawBlock } from "banani";
|
||||||
|
|
||||||
export interface DomainBlock {
|
export interface DomainBlock {
|
||||||
type: string;
|
type: "transfer" | "receive" | "metadata" | "resolver" | "freeze";
|
||||||
block: AccountHistoryRawBlock;
|
block: AccountHistoryRawBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +24,11 @@ export interface DomainResolver extends DomainBlock {
|
|||||||
resolved_address: Address;
|
resolved_address: Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DomainBlocks = DomainTransfer | DomainReceive | DomainMetadata | DomainResolver;
|
export interface DomainFreeze extends DomainBlock {
|
||||||
|
type: "freeze";
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DomainBlocks = DomainTransfer | DomainReceive | DomainMetadata | DomainResolver | DomainFreeze;
|
||||||
|
|
||||||
export interface Domain {
|
export interface Domain {
|
||||||
tld: Address;
|
tld: Address;
|
||||||
|
|||||||
2
util.ts
2
util.ts
@@ -52,10 +52,12 @@ export function base58_to_hex(base58: string): string {
|
|||||||
return uint8array_to_hex(bigint_to_uint8array(bint, 34));
|
return uint8array_to_hex(bigint_to_uint8array(bint, 34));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** IPFS CID v0 to Banano address */
|
||||||
export function cid_v0_to_address(cid_v0: string): Address {
|
export function cid_v0_to_address(cid_v0: string): Address {
|
||||||
return get_address_from_public_key(base58_to_hex(cid_v0).slice(4));
|
return get_address_from_public_key(base58_to_hex(cid_v0).slice(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Banano address to IPFS CID v0 */
|
||||||
export function address_to_cid_v0(address: Address): string {
|
export function address_to_cid_v0(address: Address): string {
|
||||||
return hex_to_base58("1220" + get_public_key_from_address(address));
|
return hex_to_base58("1220" + get_public_key_from_address(address));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user