Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The Oxen blockchain is a private payments system that enables the creation of many privacy-preserving applications
The Oxen blockchain and the $OXEN token are at the heart of Oxen. Together they bring privacy, incentivisation, and decentralisation to the Oxen tech stack.
Oxen's blockchain is maintained by the Oxen Service Node network, a network of blockchain nodes operated by members of the Oxen community. Running a service node requires staking — which means voluntarily locking — a certain amount of $OXEN tokens.
The staking requirement to run a service node is currently fixed at 15,000 $OXEN or 3,750 $OXEN for a shared node.
In exchange for maintaining reliable and trustworthy blockchain nodes, node operators periodically receive rewards in the form of $OXEN tokens.
Oxen was originally forked from Monero, and it's still based on the CryptoNote protocol. From these beginnings, Oxen has inherited world class privacy and security features — including ring signatures, stealth addresses, and ring confidential transactions. Just like $XMR, $OXEN is fungible, private, and untraceable.
The Oxen blockchain got started in 2018, with its first ever block being confirmed on March 5 of that year. Ever since then, the blockchain has been successfully and securely operating. On October 15 2019, we made the transition to Pulse — making Oxen one of the first ever Proof of Stake CryptoNote projects. The entire history of the Oxen blockchain can be easily viewed via this block explorer. As for the future, you can stay up to date on the project by checking out our Oxen Labs Updates.
The Oxen blockchain also boasts Blink — truly private, instant transactions. Blink allows you to make transactions with all the confidence Monero enthusiasts love, but with a 1 second transaction time. Blink gives $OXEN the potential to be used as a true means of value exchange — not just storage — in a way no other coin can match.
Thanks to the incredible power of Oxen Service Nodes, Oxen is climbing to heights most blockchain projects can't dream of reaching. Get involved now by downloading the Oxen Wallet, running your own service node, or trying out some of the products built on top of the Oxen blockchain — like Session and Lokinet.
Oxen is an ecosystem of privacy tools built on top of a fully decentralised layer-1 blockchain.
The Oxen Network is transitioning to the Session Network. More information here.
Service Node operators and contributors can participate in the Service Node Bonus Program to earn additional Session Tokens. More information can be found here.
Oxen can be swapped for the new Session Token using the Oxen Coin Claims program. More information can be found here.
Oxen is one of the largest app ecosystems in the entire crypto industry. Applications like Session and Lokinet are currently servicing hundreds of thousands of active users thanks to the power of the Oxen Service Node Network.
The network is powered by the Oxen blockchain, a privacy preserving cryptocurrency network that enables fast and private value transfer. The blockchain is maintained by a distributed network of community-operated 🖥 Oxen Service Nodes, which run all the network features and services offered by Oxen's tech stack.
Oxen was originally forked from Monero, and it's still based on the CryptoNote protocol. From these beginnings, Oxen has inherited world class privacy and security features — including ring signatures, stealth addresses, and ring confidential transactions. Just like $XMR, $OXEN is fungible, private, and untraceable.
Oxen is fully proof of stake, with a set of incentivised nodes called Oxen Service Nodes maintaining an securing the blockchain, providing services to Oxen Apps, and receiving block rewards.
Session — An end-to-end encrypted, decentralised messaging app. Because Session doesn’t require any identifying information—such as a phone number or email address—to sign up, it has become popular with civil rights groups, whistleblowers, and other people who require high levels of privacy and anonymity.
Lokinet — An onion-router that allows people to browse the internet privately and securely. Lokinet operates on the network layer and is therefore able to onion-route any IP-based protocol, making it fast, dynamic, and adaptable.
Oxen has a robust token burning scheme designed to keep inflation under control
A crucial consideration for any tokenomics system with an indefinite emissions tail is how to keep inflation under control. In short: How can we keep rewarding service nodes indefinitely without also ending up with so much $OXEN floating around that the token becomes worthless?
$OXEN solves the inflation problem through a robust token burning scheme. This means that the effective net emissions are lower than they may seem, because most routine interactions with the Oxen network, including Blink transactions and ONS name purchases, provably burn a certain amount of $OXEN.
Blink fees are 0.05 $OXEN per transaction output, plus a very small per-byte amount of $OXEN; all transactions have at least 2 outputs (recipient(s) and change), so the effective fee is around 0.101 $OXEN for a typical simple transaction
Of that fee, 40% goes to the service node that constructs the block validating the transaction (forming part of that service node’s reward), and the remaining 60% (i.e. around 0.06 $OXEN for a typical transaction) is burned
Basic ONS registrations burn 7 $OXEN (for Session/Wallet namespace registrations, a registration lasts forever; for Lokinet, a basic registration lasts for 1 year)
You can also buy 2, 5, and 10-year Lokinet registrations for 2x, 4x, or 6x the basic fee, respectively
We periodically reevaluate and adjust fees and burn amounts to maintain reasonable levels relative to the price of $OXEN. For example, in the Valiant Vidar hardfork, the Blink fees and burn ratios were adjusted from approx. 0.2 $OXEN fee with 80% burned in a typical transaction to approx. 0.1 $OXEN fee with 60% burned.
You can view the total burned $OXEN in the block explorer.
You can find all of our Oxen wallet releases here
Need some help using our wallets? Check out the Oxen wallet guides. You can also find out more about setting up service nodes and staking from our wallets.
The Oxen GUI Wallet is the most user friendly Oxen Wallet, and is perfect for beginners or those simply looking to send or store their OXEN.
The CLI wallet is for more advanced users, and offers more tools to interact with the Oxen blockchain.
Oxen GUI Wallet v1.8.1
Oxen CLI Wallet (packaged with Oxen Core)
Oxen GUI Wallet v1.8.1
Oxen CLI Wallet (packaged with Oxen Core)
Oxen GUI Wallet v1.8.1
Oxen CLI Wallet (packaged with Oxen Core)
Bink is Oxen's revolutionary instant payment system
Blink is $OXEN’s instant payments mechanism. We’re leveraging the Oxen Service Node network to confirm transactions before they’re entered into the blockchain, while maintaining the privacy, anonymity, and security you expect from $OXEN. Blink is the first and only instant payment solution for a CryptoNote-based privacy coin.
Normal $OXEN transactions are sent to a pool of unconfirmed transactions (the mempool), where they sit until randomly selected for inclusion in a new block to be added to the blockchain ledger. This can take several minutes, and while this is fine for many transactions, sometimes people need transactions that are private, anonymous, and instant. Enter Blink.
When a Blink transaction is made, the transaction makes a few extra stops on the way to the mempool — but, paradoxically, those extra stops make the transaction effectively instant. Blink transactions look like this:
Blink transaction is sent to two quorums (randomly-selected groups of 10 Oxen Service Nodes)
Quorums check transaction for legitimacy
Malicious or invalid transactions (e.g. duplicates of a previous transaction, or an attempt to spend $OXEN which does not belong to the sender) are denied
Valid transactions are confirmed by the quorums
Sender and receiver see transaction confirmation
Blink transaction is passed to mempool for inclusion in blockchain
With Blink, $OXEN is the first cryptocurrency to offer secure, private, anonymous transactions in real-time. The possibilities are endless — limited only by your imagination. Powered by Blink, $OXEN presents a viable solution for privacy-conscious point-of-sale applications, and any other situation where users want security, privacy, and anonymity in the blink of an eye.
Learn about the economics of the Oxen token
The Oxen network is run by a decentralised network of incentivised nodes called .
As the workhorses of the network, service nodes get the lion's share of the reward: 16.5 $OXEN per block.
This results in the creation of 11,880 $OXEN per day.
Because of the nature of , a large proportion of $OXEN's total supply is locked in service nodes and unavailable on the market. On top of this, our research has shown that people earning rewards through staked nodes are much more likely to hold their tokens and continue participating in the network than those who earnt their tokens via mining.
These two qualities help increase buy pressure and decrease sell pressure in $OXEN markets, respectively.
More details about the cryptoeconomic theory which underpins Oxen .
The not-for-profit receives a governance reward of 9240 $OXEN every 7 days. This reward is used to pay for development, marketing, and community projects, more information about how the Oxen treasury and governance reward is managed can be found on the website.
Check out our support links below!
Having trouble, want to check if you're experiencing a bug, or found an issue with the Oxen Docs? Let us know! The Oxen team is always happy to help.
Check out our support centre , where you can browse our articles or submit a ticket if those don't cut it!
You should also consider joining the Oxen community on or , our team is active in those channels and our community is always quite helpful too.
This page provides a more in-depth look at the technical side of Pulse, Oxen's PoS consensus mechanism
Pulse is 's Proof of Stake (PoS) scheme. There are various reasons this scheme was implemented in favour of the more popular blockchain consensus mechanism, Proof of Work (Pow).
Pulse makes Oxen more secure, more sustainable, and more powerful.
Every 120 seconds, an active is chosen to create a new candidate block. This one true service node creates a candidate block and sends it to 11 randomly chosen validators.
Validators are service nodes tasked with independently assessing the candidate block and ensuring it does not contain any duplicate transactions (or any other malicious activitiy). If 7 of the 11 validators verify the block's legitimacy, it can be published to the network as a valid block.
This process is then repeated to create the next block.
Thanks to Pulse, it is both difficult and unprofitable to attempt an attack on the Oxen network. At the core of any blockchain's security is its consensus mechanism. There are a few critical attacks that blockchains must be secured against, which Proof of Stake consensus schemes excel at thwarting — making sure the value stored on the Oxen blockchain is safe.
In a Proof of Work blockchain, double spending a token requires an attacker to secretly produce an alternate blockchain with more cumulative difficulty, reverse a previously spent transaction, and then create a new transaction with the same token(s).
Unless the attacker is using sophisticated attacks — such as selfish mining or cartels — this requires the miner to obtain 51% of the entire network's hash power.
Hash power is generally equivalent to computing power — more computing power, more hash power. This means the attacker only needs to acquire enough computing power relative to the size of the network to perform a 51% attack.
Performing the same attack against a PoS blockchain like Oxen's is a little different. Without considering more sophisticated attacks, the attacker would need to gain control of half of the nodes in the network to pull off a 51% attack.
Because Oxen is a finite resource, and its availability is reduced with each node that is created, conducting this attack would be many, many times more expensive than the equivalent attack on a PoW blockchain.
Increasing sunken cost of an attack on Oxen
The resources required to attack a PoW blockchain retain their value after the attack — that is, the computing power purchased to complete the attack can be used again to attack another blockchain, used to complete other computing tasks, or sold.
However, the same assault on a PoS blockchain requires you to purchase the token associated with that specific network. Assuming a successful attack would devalue the token, anyone hoping to attack a PoS blockchain will likely have trouble recouping the cost of their attack.
Checkpointing
Checkpointing provides additional 🛡 defence on top of Pulse. Every four blocks, the Oxen blockchain records a checkpoint — taking a snapshot of everything before it on the blockchain. Nothing transactions older than 2 checkpoints (also known as 8 blocks) can ever be changed.
This means that even if Pulse was somehow compromised, the Oxen blockchain would still be protected.
Checkpointing also provides additional protection against more sophisticated (and luck-dependent) attacks.
As the blockchain space grows, we have to start seriously considering whether our current models are sustainable — higher sustainability, more scope for long-term growth.
Environmental and economic sustainability are becoming increasingly pertinent issues in the tech world, and this is especially true in blockchain.
PoW consensus, while serviceable for securing the blockchain, has an inescapable flaw — it is extremely inefficient, and this problem becomes worse as the network scales.
Lots of major players in the blockchain world have thrown their weight behind PoS — most notably, Ethereum.
This is largely because PoS is more scaleable, more flexible, and easier to participate in. PoS is what will finally bring blockchain to the masses.
This is the nitty-gritty of exactly how Pulse works. If you're only interested in the why of Pulse, all the information you need is above, but for the how, read on.
Proposal round
A single leader is sequentially chosen from the Oxen Service Node list, as well as a group of 11 validators chosen deterministically using a random value included in the previous block.
The leader scans the transaction pool and collects valid transactions into a block.With this information, the leader creates a candidate block.
The leader is rewarded according to the service node coinbase formula, and receives all transaction fees included in the block.
The leader then signs this candidate block and sends it to all 11 validators.
Each validator also sends the candidate block to 3 other validators, ensuring all validators successfully receive it.
Commit round
Every validator now generates a 128 bit integer, and sends a hash of that integer to all other validators.
Reveal round
Validators will then reveal the pre-image of the hash — which in is the random integer they hashed during the commit round — to all other validators. All validators should now have a subset of the revealed values, which they can combine to produce a new random value.
Validators add this value to the candidate block, signing the resultant block.
This signature is then sent to all other validators.
Block submission
Each validator is then able to check the validity of each of the other validator's signatures, ensuring they are all signing both the same candidate block and the same combined random integer.
Once signatures have been validated, any validator in the quorum may submit a block to the network which includes at least 7 validator signatures.
120 second block time
Cannot be significantly biased by any one member of the quorum
Tolerates failure or malfeasance of up to ~45% of service nodes
There is only ever one way Pulse can fail: a timeout.
Timeouts and swap blocks
A timeout occurs when a valid block is not produced after 120 seconds.
As soon as the next leader realises there has been a timeout, they can immediately start building and distributing their own candidate block — containing a special “swap” tag.
If this block is signed by the validators, the swap tag will indicate that there was a quorum failure to both newly syncing nodes and nodes which have been offline.
Demerits and de-registrations
Validators in a quorum can submit intent to demerit messages at any stage for their leader or any peer validator(s) they feel haven't followed the protocol.
For example, if a leader never publishes a candidate block, any validator in the quorum may send an intent to demerit message to their other peers. If this message is signed by the majority of other validators it may be submitted to the network as a demerit point message.
This message is not a transaction, and simply propagates through the p2p layer.
To get a better understanding of Pulse, it is worth discussing what happens in some common failure cases.
The leader doesn't submit a candidate block
Not enough validators participate in the commit or reveal rounds
Validators sign two different blocks
Validators are unable to submit a block due to differences in revealed values
Leader doesn't submit a candidate block
If a leader fails to construct and send a candidate block, the validators will be triggered to submit an intent to demerit message.
If this message is signed by a simple majority of the quorum, a demerit point is be applied to the leader and the next leader creates a swap block.
Not enough validators participate in the commit or reveal rounds
Although all Oxen Service Nodes are incentivised to cooperate in order to avoid demerits, some participants may either act maliciously or simply fail.
The protocol should be able to tolerate the failure of 6 of 11 validator nodes during the commit reveal stage.
As above, any validator that doesn't participate in a commit round, a reveal round, or reveals a different value from their commitment can be flagged by other validators with an intent to demerit message. If this message is signed by a majority of nodes, this message is submitted to the network as evidence of a node’s non-performance in a block creation quorum.
If more than 6 of 11 nodes don't participate in the commit or reveal round, the quorum will not be able to create a block — which means the next quorum can take over block creation once a timeout occurs.
Validators are unable to submit a block due to differences in revealed values
There may be a number of cases where not all of the service nodes correctly receive all of the committed or revealed values. This will result in differing final random integers being calculated by the validators.
As with other errors, the scheme will progress normally as long as the revealed values for 7 of the 11 validators match. Nodes with invalid revealed values can query the other validators in their quorum again to receive any values they missed during the two rounds.
If more than 7 nodes disagree on the final revealed value, then the scheme will fail after once a timeout occurs and the next leader produces a swap block.
Validator signs two different blocks
Any service node, including a validator or leader, may submit a deregistration transaction if they can produce signatures from any other service node that signs multiple blocks which compete for the same height or signs a competing chain once more than two checkpoints have been applied.
This means any node that signs blocks indiscriminately in block creation quorums will be immediately removed from the network with their funds locked.
Stake grinding usually refers to a class of attacks where a validator or leader can iterate values to bias the selection of the next chosen validator. Since validators are chosen by using a collaboratively generated random integer in each block, it is possible to bias the results of the scheme. However, the only way to actually do this is for a validator to chooses to hide the value they shared during the commit round.
In the context of Oxen Service Node selection for the next quorum, this biasing is extremely weak, and the action of committing but failing to reveal a value leads to a demerit message being submitted for the validator, making this attack infeasible.
Long range attacks target nodes that are syncing the chain, or that are offline for a period of time — attempting to convince them of an alternate chain state.
This is possible because old service nodes can use previously held service node keys to re-sign blocks that appear as alternate chains.
The Oxen blockchain already provides a solution for online nodes through service node checkpointing. This prevents service nodes from altering blocks that have received more than 2 checkpoints.
However, tackling the problem of nodes which go offline and miss more than two checkpoints in a row or nodes who are syncing for the first time is more difficult.
Syncing nodes or partially offline nodes
When a node has no previous state of the blockchain, or has been offline long enough to miss enough checkpoints that it is infeasible for it to validate the non alteration of blocks, it must use an external trusted source to correctly identify the main chain. This is usually referred to as weak subjectivity.
The easiest way to solve this issue is to allow syncing service nodes, and service nodes which have been offline to refer to the seed nodes and ascertain which is the true chain. To implement weak subjectivity for Pulse, seed nodes should provide a list of the latest checkpoints, so that when a client is syncing they can ensure they're syncing to the correct chain — and not being segmented onto a network with valid but altered signatures.
The ‘nothing at stake’ problem references a validator’s tendency to sign or authorise multiple competing blocks in a Proof of Stake system. They are incentivised to do this because they can’t be sure which chain will become the true chain in the long term, thereby they should sign competing blocks to ensure they don't miss rewards.
With Pulse, the ‘nothing at stake’ problem is prevented by allowing nodes in the network to submit evidence of double signed blocks. If this evidence can be validated, the offending node can be deregistered from the network, providing a punishment for nodes who do not effectively choose a single block to sign.
Although individual service nodes have incentives to prevent DDoS attacks (so they can earn rewards and avoid demerit points), there are some protections we can offer in the Oxen software suite which can be deployed in the case that the previous block has failed to be produced. The most trivial protection is that after a failure in block creation, service nodes in the next selected quorum should ignore any connections from IP addresses which do not belong to another service node. This limits the scope of the attacker’s DDoS to only service nodes — which are costly to operate and far less numerous than a botnet-like DDoS attack. service node operators could also reasonably rate limit other service nodes on a per key basis, choosing not to respond to service nodes who put undue strain on their own networks.
Collaborative commit reveal schemes for generating random values are well studied, and limitations on such schemes are well known. The primary downside to using this type of scheme is that although committed values cannot be changed after they have been committed, a contributor to the scheme may bias the results by not revealing their committed value at all.
For example, say a block creation quorum produces a value between 0 and 10 each block, and Alice wants to run an online casino which uses this random integer to flip a coin, with bets being placed on heads or tails. Alice’s casino algorithm reads the random integer from the blockchain and if the random value is between 0-4 then the coin is tails, and if it's between 5-10 it’s heads.
A possible attack on this application would be for an Oxen Service Node operator, let’s call her “Mallory”, to wait to become a validator in a quorum, act honestly, and commit to a random value. Once she has committed to the scheme, she waits for the other validators to reveal their original integers. She can now calculate the shared random result for those validators that have revealed. Let’s suppose their combined final value will be 3. Using this information and whatever deterministic algorithm that is used to combine each validators contribution, Mallory can now decide whether or not she wants to reveal her result and add her contribution to this data.
If Mallory bets on tails and realises revealing her commitment would change the overall result to heads, then she should not reveal her commitment. If her commitment (when combined with the other commitments) still selects a number under 3, then she can reveal her committed value. Of course, the cost of not revealing a commitment is demerit points being applied to Mallory’s service node which will lead to deregistration in the event that Mallory has not revealed her commitments consistently. However, as long as Mallory’s winnings are more than the cost of being deregistered from the service node network, her dishonest actions are financially incentivised.
It should be clear from this example that service nodes can significantly bias the results of decisions which have few available outcomes, like a coin toss. So applications should not use the random integer we are creating for these type of use cases! The Oxen blockchain, however, does not use the source of randomness in this way. We use the randomness to choose service nodes in a service node list, where biasing the results has an insignificant effect as the possible outcomes are far more numerous. With Pulse, the randomness seeds an algorithm that chooses a combination of 11 nodes out of currently about 620 nodes. Mallory, in this case, would be able to choose between two (and only two) different random samples of 11 nodes from the selection of 620, but this single extra choice is highly unlikely to provide a notable benefit in terms of opportunistic selection.
Pulse targets a predictable block time of 120 seconds — excluding the rare case where block creation fails. In this case, a block would be created in the subsequent 120 seconds. This means that in a majority of cases users won't be left wondering when the next block is coming like on PoW blockchains, since blocks are be predictability created every 120 seconds.
Pulse is a robust yet simple scheme for block creation and transaction ordering in the Oxen network. Pulse does all this while increasing security and decreasing the need to use energy intensive PoW. Additionally, it's better aligned with existing incentive structures to reward those who do the most work to create order, and secure the network — service nodes.
Bitcoin, which uses PoW, per year, more than the consumption of entire countries like the Netherlands and the Phillipines — and that's just one blockchain! No one blockchain should have all that power.
PoS means a sustainable future for blockchain technology. Instead of relying on power-intensive computation, the blockchain is secured through the cooperation of , which is much more energy efficient — say goodbye to the wasteful ways of PoW.
Of course, the nodes that maintain the Oxen blockchain do a lot more than just create and validate blocks — they form the backbone range of services and applications, like and . This is just the beginning of what Oxen can do with its powerful network of service nodes.
All service nodes in the Oxen network maintain a public IP address so they are reachable by other service nodes and / users. These IP addresses are held in a distributed list that anyone can access. This opens the service node network and especially block producing quorums to DDoS attacks. For example, an attacker could wait for a block to be successfully published and immediately identify the members of the next quorum who will produce a block. With this information, they could launch a DDoS attack aimed to interrupt the communication between validators, or between the leader and validators. If successful, they would prevent a new block from being produced and could continue this attack on successive quorums.
This guide explains how to stake to an Oxen Service Node via the Oxen Mobile Wallet
The latest versions of the Oxen Mobile Wallet can be found on our downloads page.
Open the Oxen Mobile Wallet, enter your password/pin, and let it fully sync to the latest blockheight.
Press the icon in the top right of the screen to open the menu.
From there, press "Stakes" to navigate to the staking section.
Next, press "Start Staking" to begin the staking process
Search for nodes that are awaiting contribution on https://oxensn.com.
Copy the service node public key into the box at the top of the screen labelled 'Service Node Key'
Enter the amount of Oxen you wish to stake in the other box. The minimum stake amount will be listed on https://oxensn.com, but to work it out yourself you can simply divide the amount of Oxen available to stake by the number of slots left for that Service Node.
For example, if a node had 2 slots remaining and 7500 Oxen available for stake, the minimum contribution would be 7500/2 = 3750 Oxen.
Once you have entered the Service Node public key and the amount you wish to stake, simply swipe 'Stake Oxen' to contribute to the Service Node.
Congratulations! You're all staked up, and you'll receive your Service Node rewards directly to your wallet.
To unlock your stake from a Service Node, navigate to the stakes section of the wallet your contributions will be listed. You can unstake a contribution by swiping left and confirming. Your Oxen will be unlocked after 15 days.
If something in this guide doesn't make sense, or if you’re running into issues that you can’t identify on your own, the first place to go would be the Oxen Telegram Group. Alternatively, you can find help on our other communication channels: Twitter, or Reddit.
If you've sought help through our communication channels but have not arrived at a solution for your issue, we recommend opening an issue ticket on the Session public server GitHub repository.
The Oxen CLI wallet is based on wallet first developed by Monero. The Oxen wallet includes additional commands on top of the standard monero-wallet-cli
commands, and this document goes through all the Oxen and Monero CLI commands available within oxen-wallet-cli
.
The oxen-wallet-cli
has multiple commands to conduct different operations on the Oxen Blockchain. Typing help
and pressing Enter after loading your wallet will bring up the commands that can be used.
When a wallet is generated, it will automatically have an account labelled Primary account
with index 0
. If at any time you wish to create an additional account use the command:
This command will create a subaddress which is labelled with a tag and index number. This subaddress will share the same seed as your Primary address. To ensure this new account is displayed you must type exit
to save your session.
You will note that there is now an asterisk to the left of index 1. The asterisks show us the account in which the commands we run will apply to.
Note: Restoring your wallet from your seed will not restore your accounts as the index of your subaddress data is stored on your computer within your wallet file. All the funds stored in your additional accounts will be shown in your Primary account if you need to restore your wallet from scratch.
When transferring out or receiving to a specific account we need to make sure that the account we are performing the action is the one the CLI is currently connected to. An asterisk will show which account we are connected to. In the below example the asterisk is shown to the left of Secondary account so any operations will be associated with that account.
Each of the accounts connected to your Primary address will have an index associated with them. The index number will be shown to the left of the Account column. By default, index “0” is your Primary account.
To switch between the accounts you have created run the command:
After running the command a similar output shown below will be on your terminal.
To change the label name connected to a specific Oxen Primary or Sub-address use the command:
Replacing <index>
with the index number associated with the account you wish to relabel, and replacing <label text with white spaces allowed>
with the new label you would like to name the specified account.
Below shows the current accounts and labels for a specific wallet.
Using the command account label 0 My Account
we have changed the label connected to our Primary address from “Primary account” to “My Account”.
The oxen-wallet-cli
allows you to group accounts by tagging or untagging them.
Below shows a wallet with 4 accounts, Dog, Kid 1 and Kid 2.
We can tag a single account with the following command:
When needing to perform multiple tags we can do it through one command:
Similarly we can untag accounts by running the following command:
Using the above exampled wallet we will remove our “Dog” account from “Pets”.
If you require additional information attached to a specific tag you can add a description with the following command:
For example:
To check the balance of your wallet you can run one of two commands:
balance
or balance detail
Running the command balance
will generated a simple output showing your balance and unlocked balance of the specific account you are in. For example:
While running the command balance detail
will generate a more detailed output, showing the account number, first few characters of the address, balance, unlocked balance, Outputs and the Label of the account. For example:
There are other commands that will also output the balance which have been covered by this guide, such as the account
command.
To show the blockchain height run the command:
Blackballing transactions allows you to ignore others' outputs (containers of money) that are known to be spent in a certain transaction.
For example let’s imagine that txid: 4f4b371a0da8858bbeab8a40ff37de1f6ff33e64a616e5ced8239062570b7542
is known to be fake and if this txid is seen within a RingCT transaction the network can assume it is fake, therefore an actor has a better chance of deducing the real transaction within the RingCT.
By blackballing the above txid we remove the chance of it being used within our RingCT.
To do this we will use the following command:
For example:
To check if the txid was added to our list of txids not to use we can use the following command:
If the txid is on our list the following will output:
Alternatively if the txid is not on our list the following will output:
To unblackball a txid use the following command:
For example:
Reserve Proofs are used to generate a signature proving that you own an amount of $OXEN, with the option to sign the reserve proof with a key.
For example let’s imagine you see a car for sale but they will accept $OXEN as payment, however they have advised in their online listing that they are only interested in serious buyers and require you to prove you have the $OXEN. Luckily we can use Reserve Proof commands for this proof.
To begin we will need to run the get_reserve_proof
command to generate our proof.
If the individual you are sending this proof to requires you to prove you have 1000 $OXEN you will need to replace the section (all|<amount>)
with a 1000, otherwise replace it with the amount you need to prove you have reserved. If you want to put an extra layer of encryption over the file replace [<message>]
with a password.
Your command will similar to the below command:
The CLI will request your wallet password and once your password is entered it will tell you it generated a signature file.
This signature file oxen_reserve_proof
will be saved in your Oxen folder, where your daemon and wallet keys are. Keep in mind every time you run the get_reserve_proof
command it will overwrite youroxen_reserve_proof
file.
You will want to send this file to the person who requires the proof. You can upload the oxen_reserve_proof
file through https://transfer.sh/ by running the command within the folder of your signature file:
The terminal will then print out a link to your signature file which you can then provide to the individual performing the check.
Make sure you provide the following to the individual who will be checking your reserve proof:
The oxen_reserve_proof file through the transfer.sh link.
The Oxen address you are proving has $OXEN in it.
The <message>
if you encrypted the file.
To check a reserve proof we need to first have the oxen_reserve_proof
file in our Oxen folder.
If you do not have the oxen_reserve_proof
file in your Oxen folder request the individual sending the file to you to use https://transfer.sh/, once they send you the link to their oxen_reserve_proof
you can use the following command to download it.
Replacing <link>
with the link to download the oxen_reserve_proof
.
Now that the oxen_reserve_proof
is in our folder we can run the following command:
Where <address>
is the address of the wallet where the command get_reserve_proof was ran. <signature_file>
is the file that was received from the individual sending you the reserve proof, normally generated as oxen_reserve_proof
and <message>
is the key set by the individual who sent you the reserve proof.
Therefor for the previous example where we created a reserve proof for 1000 $OXEN and signed with “car”, we would run the command:
If all goes well, the terminal will output the following:
You may note that it shows a reserve proof which is greater than 1000, this is because the command is adding up all the transactions into the address specified until it is greater than the reserve proof set.
Spend Proofs are used to generate a signature proving that you generated a TXID, with the option to sign the spend proof with a key.
For example let’s imagine you have bought a car from a dealership with $OXEN and have sent 1000 $OXEN to the seller. Unfortunately the dealer does not know which transaction is yours as he has received 5 transactions of 1000 $OXEN in the same block for 5 different cars. He knows the txid’s but wants you to prove that you have generate one of the txid’s in his list. Luckily we can prove we generated the txid by using the get_spend_proof
command.
To begin we will first need to find the txid associated with our transaction. To do this run the following command in our wallet:
The terminal will output a list of transactions in and out of your address. You should have a transaction in your list with the amount you spent to the dealership. Copy the txid(by highlighting) associated with this transaction and save it in a notepad for later.
We can now run the get_spend_proof
command to generate our proof.
Replacing <txid>
with the txid of our transfer out and replacing <message>
if we want to add a password to the proof. If all went well the terminal will output the following text:
This signature file oxen_spend_proof
will be saved in your Oxen folder, where your daemon and wallet keys are. Keep in mind every time you run the get_spend_proof
command it will overwrite your oxen_spend_proof file
.
You will want to send this file to the person who requires the proof. You can upload the oxen_spend_proof file through https://transfer.sh/ by running the command within the folder of your signature file:
The terminal will then print out a link to your signature file which you can then provide to the individual performing the check. For example:
Make sure you provide the following to the individual who will be checking your reserve proof:
The oxen_spend_proof
file through the transfer.sh link.
The $OXEN transaction txid associated with the transaction you are proving you generated.
The <message>
if you encrypted the file.
To check a spend proof we need to first have the oxen_spend_proof
file in our Oxen folder and the txid associated with the transaction being proved.
If you do not have the oxen_spend_proof
file in your Oxen folder request the individual sending the file to you to use https://transfer.sh/, once they send you the link to their oxen_spend_proof
you can use the following command to download it.
Replacing <link>
with the link to download the oxen_spend_proof
.
Now that the oxen_spend_proof
is in our folder we can run the following command:
Where <txid>
is the txid associated with the transaction that is being proved. <signature_file>
is the file that was received from the individual sending you the spend proof, normally generated as oxen_spend_proof
and <message>
is the key set by the individual who sent you the spend proof.
An example would look like the following command
If all goes well, the terminal will output the following:
If you receive a Good signature
message that should be a good proof that the txid you are checking was generated from the sender. Keep in mind however that this can potentially not always be the case, considering someone could get access to someone else's computer thus having access to this file.
TX Proofs are used to generate a signature file proving that you generated a TXID, with the option to sign the spend proof with a key. TX proofs work similar to Reserve Proof’s and Spend Proofs however they show more detailed information.
For example let’s imagine you have bought a car from a dealership with $OXEN and have sent 1000 $OXEN to the seller. Unfortunately the dealer does not know which transaction is yours as he has received 5 transactions of 1000 $OXEN in the same block for 5 different cars. He knows the txid’s but wants you to prove that you have generate one of the txid’s in his list. Luckily we can prove we generated the txid by using the get_tx_proof command.
To begin we will first need to find the txid associated with our transaction. To do this run the following command in our wallet:
The terminal will output a list of transactions in and out of your address. You should have a transaction in your list with the amount you spent to the dealership. Copy the txid(by highlighting) associated with this transaction and save it in a notepad for later.
We can now run the get_tx_proof
command to generate our proof.
Replacing <txid>
with the txid of our transfer out, <address>
with the receiver's address, and replacing <message>
if we want to add a password to the proof. If all went well the terminal will output the following text:
This signature file oxen_tx_proof
will be saved in your Oxen folder, where your daemon and wallet keys are. Keep in mind every time you run the get_tx_proof
command it will overwrite your oxen_tx_proof
file.
You will want to send this file to the person who requires the proof. You can upload the oxen_tx_proof
file through https://transfer.sh/ by running the command within the folder of your signature file:
The terminal will then print out a link to your signature file which you can then provide to the individual performing the check. For example:
Make sure you provide the following to the individual who will be checking your reserve proof:
The oxen_tx_proof
file through the transfer.sh link.
The $OXEN transaction txid associated with the transaction you are proving you generated.
The receiver's Oxen address.
The <message>
if you encrypted the file.
To check a tx proof we need to first have the oxen_tx_proof
file in our Oxen folder, the receiver's address and the txid associated with the transaction being proved.
If you do not have the oxen_tx_proof
file in your Oxen folder request the individual sending the file to you to use https://transfer.sh/, once they send you the link to their oxen_tx_proof
you can use the following command to download it.
Replacing <link>
with the link to download the oxen_tx_proof
.
Now that the oxen_tx_proof
is in our folder we can run the following command:
Where <txid>
is the txid associated with the transaction that is being proved, <address>
is the receiver’s address and <signature_file>
is the file that was received from the individual sending you the tx proof, normally generated as oxen_tx_proof
and <message>
is the key set by the individual who sent you the tx proof.
An example would look like the following command:
If all goes well, the terminal will output the following:
If you receive a Good signature
message that should be a good proof that the txid you are checking was generated from the sender. Keep in mind however that this can potentially not always be the case, considering someone could get access to someone else's computer thus having access to this file.
A TX key is a private key associated with a TXid. Only the wallet that has sent the transaction can generate a TX key from the TXID that both parties can see. A TX key can be used to validate a transaction on a case by case basis. In essence, you can provide the tx key, txid and the receiver address to someone to prove you had generate that transaction.
To view the TX key of a specific transaction you have generate you will need to run the command:
Where <txid>
is the transaction id associated with the transfer out you are proving is yours.
The terminal will prompt the user for the wallet's password and then print out the tx key, which will look similar to:
Provide the <tx key>
with the <txid>
and <receiving address>
to the individual who will run the validation, thus this will prove you generated the transaction.
Once we have a <tx key>
, <txid>
and <receiving address>
from a specific transaction we can use the following command to prove they are all associated:
For the previous example we would run the following command from any Oxen wallet:
The terminal will show text of how much $OXEN the address received. It will also show how many confirmations the transaction has received from the blockchain. For example:
The oxen-wallet-cli
allows you to add notes to specific txid’s, however this note does not get stored on the blockchain, rather it is stored on client side, on the device that generates the tx_note
.
To set a tx note we will need a the <txid>
and the <message>
you want to add to the txid. For instance, if you want to add a note to a txid that is connected to your wallet run the following command to show your transactions in/out with their <txid>
’s:
To set the note to the <txid>
run the following command:
Where <txid>
is the transaction id associated to the transaction you are adding the [free text note]
too. Your command will look similar to the following example:
To view a note connected to a txid run the following command:
Where <txid>
is the transaction id that has the note connected to it. For example, if we run the command on the previous <txid>
mentioned, the terminal will display the following text:
You can also view a tx note by running the show_transfers
command, each transaction that has a note connected to it will display the text to the right of each transfer.
Changing the wallet password is only client side(locally), and if the password is forgotten the wallet can always be restored with the mnemonic seed. If you know the password to the wallet and want to change it you can run the following command:
Once the command has been run the terminal will prompt you for the current password and the new password twice. If entered correctly the terminal will go back to receiving inputs, otherwise the terminal will output an error such as Passwords do not match! Please try again
or Error: invalid password
.
Your seed passphrase is a 25 word phrase which is used to recover access to your wallet on a client or gui and is. The command encrypted_seed
allows your to add an additional password, or encryption layer, to your 25 word mnemonic seed. Encrypting your seed will stop others from recovering access to your wallet if they somehow gain access to your 25 word mnemonic seed as they will not have the passphrase that decrypts them. This means, your passphrase should not be written or saved in the same location as your encrypted 25 word mnemonic seed phrase.
To encrypt your seed run the following command:
Initially the CLI wallet will prompt you to enter your wallet password. Next it will request for your seed encryption passphrase, enter in your desired password/passphrase once, click enter, then type the passphrase in again.
The wallet will output your mnemonic seed which is a 25 word passphrase. It is generally best practice to write these 25 words down and store them somewhere safe and securely, write your passphrase down(which is the phrase you used to encrypt the 25 words) and store this somewhere else. Storing the 25 words with the passphrase in a file on your computer that is not encrypted is giving others easier access to your mnemonic seed.
Here's a quick overview of the services provided by the Oxen blockchain
The Oxen Wallet, available in user-friendly GUI or powerful CLI versions, enables you to send and receive private anonymous transactions in the blink of an eye. You can download your preferred Wallet version here.
Running an Oxen Service Node is a great way to grow the Oxen network and support the project while receiving $OXEN rewards for your valuable contribution. Check out our guides to setting up a service node and staking to a service node, or see here for some service node tools and utilities to help with starting up and maintaining your service nodes.
Oxen Name System enables you to register alphanumeric names to be used in place of the long, hard-to-use default formats for Lokinet addresses, Session IDs, and Oxen Wallet addresses. For a look at registering names using ONS, check out our guide.
Thinking of running an Oxen Service Node? Awesome! The guide below will help you configure a device with the necessary Service Node software packages, and stake $OXEN to register the node on the Oxen network.
Note: This guide assumes some familiarity with the command line and running a Linux server. For a more detailed walkthrough, check out our full Service Node set-up guide.
One of:
Debian 12 ("bookworm")
Debian 11 ("bullseye")
Ubuntu 22.04 ("jammy")
Ubuntu 20.04 ("focal")
Recommended: the latest Debian stable or Ubuntu LTS release (12 and 22.04, respectively, as of the time of writing).
Note: There are strict uptime requirements for Service Nodes (see Service Node deregistration). It is strongly discouraged to run a Service Node on a device that will not be continuously on-line. We recommend running your Service Node on a VPS with a reputable provider.
If you are using a firewall then you should ensure that the following ports (TCP unless otherwise noted) are open and reachable:
Port 22020 (storage server connectivity; requires both TCP and UDP)
Port 22021 (client to storage server)
Port 22022 (blockchain syncing)
Port 22025 (Service Node to Service Node)
Port 1090 (Lokinet router data; UDP only)
Configuring a new Oxen Service Node is as simple as running the following 4 commands on the Linux server you want to become a node (these commands will work on Debian and Ubuntu; modifications may be necessary for other Linux distributions):
The services will run via systemd as oxen-node.service
, oxen-storage-server.service
, and lokinet-router.service
.
Once the blockchain has synced to the server (which can take several hours), your Service Node will be ready to be staked. You can use the oxend status
command to check the sync progress.
Alternatively, the blockchain can typically be downloaded in a fraction of the time required to sync it via the Service Node network, using the following command:
To add the Oxen repository, run the following commands.
Note: You only need to follow this step once, to set up the repository. The repository will subsequently be automatically updated whenever you fetch new system updates.
This first command installs the public key used to sign the Oxen Service Node packages:
The second command tells apt
where to find the packages. Note: Replace <DISTRO>
with the appropriate value to match your operating system.
To find your <DISTRO>
run the following command: lsb_release -sc
Alternatively, <DISTRO>
can be found in the following list:
sid (Debian testing/unstable)
bullseye (Debian 11)
buster (Debian 10)
jammy (Ubuntu 22.04)
focal (Ubuntu 20.04)
bionic (Ubuntu 18.04)
Then resync your package repositories with:
To configure your Service Node, simply install the oxen-service-node
package:
This will detect your public IP (or allow you to enter it yourself) and automatically update the /etc/oxen/oxen.conf
configuration file with the necessary additional settings to run a Service Node.
Congratulations! Your Service Node is now ready to be registered and staked.
To prepare your Service Node for registration, run the following command:
This will prompt you for some registration details, then output a registration command. Copy the output from this command in preparation for the next step.
Note: You can safely run this command multiple times if you change your mind about some of the registration questions before you submit the registration.
To stake and register your Service Node, open the Oxen GUI wallet. Make sure your wallet has a balance of at least 15,000 $OXEN to meet the Service Node staking requirement (less if you're configuring a shared Service Node). Navigate to the Service Nodes
tab > Registration
section, and paste the output from the above command, then click Register Service Node.
Done! Your staking transaction will now be submitted to the network. After a short delay, your Service Node will be registered and start contributing to the network (and receiving rewards!).
You can easily check if your Service Node is registered on the network. First, connect to the VPS where the Service Node is running and run the following command to retrieve your Service Node's public key:
This will output a bunch of information about your Service Node, but there's one part we're interested in at this stage: The long string of random letters and numbers after the characters SN:
. This string is your Service Node's public key, used to identify your Service Node on the list of registered and operational Service Nodes. Select and copy the public key (do not copy any of the surrounding information).
You can now jump onto oxen.observer, open the full list of active Service Nodes, and use Cmd+F
/Ctrl+F
to check if your Service Node's public key appears in the list.
We highly recommend setting up monitoring for your Service Node. This is as simple as calling on the services of our Telegram or Discord bot. Contact @OxenSNBot
on Telegram or OxenSNBot#5812
on Discord and type /start
or $help
respectively to get started.
Another helpful tool is Konstantin Ullrich's Oxen Service Node Operator app for Android.
When a new release is available, upgrading is as simple as syncing your repositories:
Then installing any updates using:
Note that this will install both updated Oxen packages and any available system updates (this is generally a good thing!)
During the upgrade, the running instance of oxend
will be restarted to ensure that the updated oxend
is now active.
If, for some reason, you want to install only updated Oxen package upgrades, but not other system packages, then instead of sudo apt upgrade
you can use:
To show backup information for your Service Node's secret key (for future recovery/migration):
For service nodes originally installed before 8.x there will be a /var/lib/oxen/key file that must also be backed up (if this file does not exist then you do not need it):
Restore from SN secret key:
and, only when restoring from an older installation with an additional .../key
file:
Having trouble? Just head to our Support section.
To fully restore your wallet and be able to view balance and make transactions, having your seed stored will be enough. You don't need your wallet password or other keys to restore the wallet once you have a seed phrase.
Download the latest release of wallet CLI software for your desired operating system
Unzip oxen-[operating-system]-[platform]-[version].zip
file
Open a Command Prompt (Windows) or Terminal (Linux / OSX) and navigate to the wallet folder
Run wallet with --restore-deterministic-wallet
argument: ./oxen-wallet-cli --restore-deterministic-wallet
You will be prompted to enter a wallet name and click [Enter]. You can enter any name here, use something memorable and meaningful.
You will be prompted to enter 25 word mnemonic seed you have stored. Paste it and press [Enter].
If you have a seed encryption passphrase, enter it on the next step. Otherwise, press [Enter].
You will be prompted for a password. Enter a new password that follows the Password Policy and press [Enter].
Confirm password and press [Enter].
If you know the block height at which wallet was created or a first transaction was made, you can enter it here. Specifying a blockchain height will help to scan the wallet faster.
If you don't know a specific blockchain height, press [Enter] for scanning from block height 0.
For refresh process to start, you need to have your daemon running. Another option would be to use a remote node. For that, use the following command, replacing and with the host and port number of the remote node you are connecting to:
Once refresh is done, you can use your full functioning restored wallet. Your public wallet address will remain the same.
Oxen Service Nodes provide the underlying support for the Oxen Network
Oxen’s networking functionality, scalability, and decentralisation tech stack is powered by a set of incentivised nodes called Oxen Service Nodes. To operate a service node, an operator time-locks 15,000 $OXEN, and the service node begins providing a minimum level of bandwidth and storage to the network. In return for their services, service node operators receive a portion of the block reward from each block mined on the Oxen blockchain.
The resulting network benefits from market-based resistance to Sybil attacks, addressing a range of problems with existing onion routers and privacy-centric services. This resistance is based on supply and demand interactions which help prevent single actors from possessing a large enough stake in Oxen to have a significant negative impact on the second-layer privacy services Oxen provides. DASH first theorised that cryptoeconomics can provide a network with properties of Sybil attack resistance. In our case, as an attacker accumulates $OXEN, the circulating supply decreases, in turn applying demand-side pressure and driving the price of $OXEN up. This effect spirals, making it increasingly costly for additional $OXEN to be purchased and thus making an attack prohibitively expensive.
To maintain this protection, Oxen encourages active suppression of the circulating supply. In particular, the emissions curve and staking requirement have been designed to ensure enough circulating supply is locked (and reasonable rewards are provided to operators) to ensure Sybil attack resistance.
Just looking for a guide on setting up a service node? Click here. Interested in staking into a shared service node? Check out our Staking Guide.
An Oxen Service Node becomes active on the network when its owner stakes (locks up) the required amount of $OXEN, which submits a registration transaction. Once accepted by the network, the service node becomes eligible to receive block rewards. Multiple participants can stake to a single service node, combining their smaller stakes to meet the 15,000 $OXEN staking requirement. The block reward can be automatically distributed among the participants in a ratio proportional to each participant's staking contribution.
Once active on the network, Oxen Service Nodes are required to:
Monitor other service nodes and vote on their performance
Create new blocks on the Oxen blockchain (see Pulse)
Receive, temporarily store, and forward encrypted messages (see Session)
Participate in quorums to enable instant $OXEN transactions (see Blink)
Route end-user internet traffic (see Lokinet)
Pulse is Oxen's Proof of Stake consensus mechanism
Fundamentally, every blockchain — including Oxen — is exactly what it says in the name: a chain of blocks. One 'block' in the Oxen blockchain is made up of a set of $OXEN transactions which have been deemed valid by the network. But when the network consists of thousands of computers all over the world, how does it come to consensus about the state of the blockchain?
That's where Pulse comes in.
Pulse is Oxen's implementation of the 'Proof of Stake' consensus mechanism, and it forms the foundation of the Oxen Service Node network. Let's dive into how it works and why we use it.
In our Proof of Stake (PoS) consensus system, active Oxen Service Nodes are randomly selected to create and publish new blocks of transactions to the blockchain approximately every 2 minutes, with each node being rewarded for doing so.
Once a service node has been selected to create a block, a set of other nodes (the validators) are chosen to validate the new block — checking to ensure it doesn't contain duplicate transactions or any other potentially malicious activity. Once these validator nodes have verified the block’s legitimacy, the block is published to the blockchain.
In a PoS-based blockchain, an attacker would need to control more than 50% of the total supply of staked or stakeable cryptocurrency tokens in order to carry out a 51% attack (allowing them to publish fake or invalid transactions, re-order the blockchain, etc.).
Acquiring this much of the total supply can be extremely expensive — and in some PoS-based blockchains, it be nearly (or completely) impossible. When crypto tokens are staked into nodes, they are locked for a pre-determined amount of time. This means they're removed from the marketplace and can't be bought. If more than 50% of the total cryptocurrency supply for a given blockchain network is staked, a 51% attack becomes extremely unlikely, because for an external attacker (i.e. someone not already invested in the network), buying up or otherwise being able to control enough tokens to control more than half the nodes on the network becomes almost impossible. And there's a second layer of security here, too: if someone does buy up such a huge amount of tokens that they could gain control of the network, they would then be disincentivised from wanting to attack the network simply because attacking the network would harm the value of their tokens — once they're invested, they're simply better off acting in good faith, so their tokens gain value rather than losing value.
This document will tell you exactly how to set up and operate the Oxen GUI wallet. You can download the appropriate GUI Wallet for your desktop operating system here.
Mac and Linux users skip to Step 1.
Open the executable file we downloaded from the Oxen Github Oxen.Electron.Wallet.Setup.X.X.X-windows.exe
to start installion.
When installing the wallet the Windows Defender SmartScreen will prevent you from opening it unless you give the file permission.
Click Run anyway
to give the executable permission.
Now run through the installation prompts and then click install.
Once the installation has finalised open the Oxen Wallet by clicking your "Windows" key or the start menu and searching for oxen electron wallet
.
Once the installation has finalised open the Oxen Wallet by clicking your "Windows" key or the start menu and searching for oxen electron wallet
.
Once opened the wallet will need to be configured.
Default settings are fine to use.
This is not required but if you would like to run your own node and broadcast your own transactions check the
Local + Remote Daemon
or theLocal Daemon Only
option.
Click Next
when ready.
Once your settings have been configured if you do not already have a wallet generated yet then your screen will look like the following:
To create a new wallet click the Create new wallet
button.
Next fill in the input fields that are required. It is recommended that you should consider encrypting your key with an optional password.
Once input boxes are filled in click CREATE WALLET
button.
To import a wallet from seed click the Restore wallet from seed
button.
Next fill in the following input fields:
Wallet Name: Enter a name for your wallet.
Mnemonic Seed: Enter the seed phrase that was generated when intially creating your wallet.
Restore from Date: Enter the date or blockheight in which you want to restore your wallet from.
It is quicker to restore from the date in which you generated the wallet.
Password: Enter an optional password.
Confirm Password: Enter the same password to confirm spelling.
Once input boxes are filled in click RESTORE WALLET
button.
When installing the Oxen Wallet, overzealous antivirus software can sometimes block the wallet or some of its components from functioning, or even delete them entirely. To avoid these issues on Windows, follow the below steps.
Note: when you reach Step 6 (downloading the Oxen Wallet), ensure you are downloading the Wallet directly from an official source: either here on the Oxen Docs, or on the official Oxen Github releases page.
For the purposes of this example, our images show how to do this on Windows Defender
Create a folder called “Wallet” at the root of your C: drive (or another convenient location)
Open your antivirus program and go to “Manage Exceptions”, “Exceptions”, "Exclusions", or similar:
Click “Add an exception”, "Add an exclusion", or similar:
Select your Wallet folder as the location for the exception:
Disable protection features for this folder:
Download the latest version of the Oxen Wallet directly into the Wallet folder:
Run the Oxen Wallet installer and select the Wallet folder as the install location:
Check your antivirus program’s firewall and ensure all executables named “Oxen xxx” are permitted through the firewall:
Congratulations! You can now proceed to our GUI Wallet setup guide as normal.
Note: If you’re using Bitdefender specifically, and your wallet still does not function after following the above steps exactly, disable Advanced Threat Detection under Features
Just looking for the latest Oxen Wallet releases? Head to our downloads page.
The Oxen Wallet is your gateway to private decentralised transactions and communications. It allows you to hold and secure your $OXEN, stake into Oxen Service Nodes, and transact with $OXEN.
The Oxen wallet stores a collection of public and private keys which can be used to receive, view, or spend $OXEN.
The wallet uses these private keys through a daemon which synchronises with the Oxen network to scan for incoming transactions and send outgoing transactions.
The Oxen GUI Wallet, also referred to as the Oxen Electron Wallet, is the most user-friendly Oxen wallet. It has a graphical interface (like most PC applications), which is perfect for beginners or those just looking to store and send their Oxen. The GUI Wallet is available for Windows, macOS, and Linux.
To download the latest release of the Oxen GUI Wallet, head to our downloads page.
Guide | Description |
---|---|
The Oxen CLI Wallet is for more advanced users, and offers additional tools to interact with the Oxen blockchain.
To download the latest release of the Oxen CLI Wallet, head to our downloads page.
Guide | Description |
---|---|
The Oxen mobile wallet allows users to access and manage their Oxen without having access to a PC. The mobile wallet is available for both iOS and Android.
To download the latest release of the Oxen mobile wallet, head to our downloads page.
This guide will walk you through using the GUI wallet for the first time. It assumes you already have the GUI wallet installed and running. If this is not the case you can download the wallet from our downloads page. Some overzealous antivirus software may take issue with the Oxen wallet, if this happens we walk you what to do about that HERE.
We will discuss in detail the process of creating & using the wallet later in this guide. But a quick overview of the GUI wallet is as follows. The wallet begins by displaying a list of your wallets and looks like this:
In this above image you can see 5 different wallets. Each wallet has a different address and holds a different amount of Oxen. Clicking on a wallet will ask you for a password which is used to decrypt the wallet file and brings you to the following page:
This is the main wallet page which contains all of the basic information about the wallet.
1. The “Total Balance” of the wallet is shown just above the centre of the screen (16,475.448 Oxen). It also lists the 'unlocked' balance directly below. If you have staked to an Oxen service node, the amount of Oxen you have staked will be unavailable to send.
2. A list of sent and received transactions can be seen at the bottom. (Showing where you have previously received funds, and also previously spent funds)
3. The long alphanumeric text in the center is the wallet address (T6SYH3Lh…). In this image the wallet operates on the Oxen testnet (A network built to practice without risking real funds), this can be identified by the address beginning with the letter “T” and the address being 98 characters long. When interacting with the Oxen mainnet (The real network) the wallet address will begin with the letter “L” and will be 95 characters long.
4. The wallet name at the top left. This name is decided by you and matches with the names on the first page. This name is simply to help you identify which wallet you are using, if you have multiple wallets.
5. Action Buttons for wallet usage. These include sending funds, receiving funds, interacting with service nodes and purchasing and managing Oxen Name Service records (ONS Records). We will go into sending and receiving in detail later.
When you first open up the GUI wallet you will need to create a wallet and setup some default settings. You will first be greeted with a language selection page. We will be walking through the English version here. Click your native language to continue to the next page:
The next page of the wallet is where you configure the network settings.
Basic Network Settings
To get started quickly and easily the following settings are recommended:
Type: Remote Daemon Only
Remote Node Host: public.loki.foundation
Remote Node Port: 22023
Additional Network Configuration Details The three radio buttons at the top of this page determine how the wallet connects to your daemon (which manages the blockchain). Remote means there is an external daemon that the wallet communicates with. Local Daemon means the wallet will spin up a subprocess for the daemon and interact with it directly.
Running a local daemon will require syncing the Oxen blockchain before you are able to interact with the wallet, which will take time. So for an immediate start, connecting to a remote daemon that the Oxen Foundation is running is the easiest option.
The downside to using a third party for your remote daemon is that it is privacy reducing (That third party will see your requests to the network). So for ultimate security one should run their own daemon, but as that is a more advanced topic we won't get into it here. If you wish to follow this route it is recommended you run the oxend daemon software separately, wait for the blockchain to sync, and from the wallet select “Remote Daemon Only” and point it at your own local daemon (Remote Node Host: Localhost). This means you do not need to keep the wallet open while syncing and have greater control over the daemon rather than letting the wallet manage the daemon. If this sounds like mumbo jumbo to you, don't stress, just choose the basic network settings above and continue.
The next page will present 3 options to decide how to create/load/import/open a wallet into the application. If you have not used the GUI wallet before will want to choose “Create new wallet”
When creating a new wallet you will need to choose the following:
Wallet Name: represents the name of the datafile and is used throughout the application to identify the wallet. Choose something that is memorable because your wallet list can become unwieldy rather quickly when creating multiple wallets. For this reason using names such as: Wallet1, Wallet2, Wallet3 etc are not recommended.
Seed language: The most important part of the wallet creation process is the creation of your “Seed Phrase”. This is shown in the next step. Select your native language here to make the recording of your seed phrase easier.
Password: Your wallet file will be encrypted by this password to prevent malicious persons from accessing your wallet if they get control of the wallet file. Please note that you can still access your wallet if you forget the password but still have the seed phrase. A password is not necessary (resulting in an unencrypted wallet save file) but it is highly recommended.
After filling in the appropriate fields click “Create Wallet”
On this page you are shown the details of your newly created wallet. At the top you can see your new wallet address which is used by other persons to send funds to you. Beneath this you can see your seed words.
Important!
Please note that these 25 seed words are by far the most important part of the wallet creation process. Write these somewhere safe! Don't lose them. If a malicious person gets access to these words they will be able to spend your funds. The Oxen team will NEVER ask you for your seed phrase and a person requesting them from you is likely a scammer trying to steal your funds.
You won’t need to regularly use these seed words. But if/when you need to recover your wallet or move the wallet to a different computer then everything can be rebuilt using these 25 words.
Click “OPEN WALLET” and you will be brought to the main wallet page discussed earlier.
When purchasing oxen from an exchange or requesting funds from another person you will need to provide your wallet address. From the main page your wallet address is the 95 character text starting with “L”. This is shown in the red box below:
If you click the “Copy Address” button to the right of the address (Shown in the green box) your wallet address will be copied to the clipboard and you can simply paste it using Ctrl-V.
When receiving funds from an exchange there will generally be some processing time from the exchange (This time varies depending on the exchange) then a transfer will occur on the blockchain which your wallet will recognise.
The wallet scans the blockchain to find transfers that belong to you, when it finds one it will be added to the transaction list at the bottom and your balance will be updated. If the wallet is not detecting your transfers the most common reason is due to the wallet not being fully synced yet.
Down the bottom of the application there is a status bar. This should be green and say Status: READY
Remote: 946353 refers to the height of the blockchain on the remote daemon. Wallet: 946353 / 946353 (100.0%) refers to how much of the blockchain the wallet has processed when looking for your transactions. The wallet has to scan all transactions on the blockchain when searching for your transactions, so this process does take some time. If the wallet is still syncing the status bar will look like this:
While Status: SYNCING is in the status bar it is normal and expected that your transactions are not processed and therefore won't be shown in the application. Please wait until the wallet show Status: READY
Both the Remote Daemon and the Wallet need to be fully synced for your wallet to work correctly.
From the main page in the application click on the “Send” button
From here you will be greeted with the page to enter in your recipients address and the amount you wish to transfer. Key things to not note this page:
Amount: This is the amount of Oxen you wish to transfer, 1 means 1 full oxen transferred
Priority: Blink is our instant transfer technology which is selected by default. Selecting slow will mean the recipient has to wait until the transfer has been confirmed in a block before seeing the payment. Choosing Blink is recommended wherever possible.
Address: The address of the recipient.
Notes: This is an optional field for noting details about the transaction such as: why are you sending it, who are you sending it to etc. This is completely optional.
Click “Send” and you will be prompted for the wallet password and then a screen will confirm the transaction details.
Click Send to broadcast the transaction to the network. Shortly afterwards the bottom of the application will display a green banner saying Transaction Successfully Sent
After this point the transaction will show up in your transaction list and your balance will be reduced by the sent amount.
Oxen allows users to stake their oxen by running service nodes which support the Oxen Network. To run a service node an operator is required to stake 15,000 oxen which they can either contribute the full amount or share the burden between multiple contributors to reduce the amount required individually. This guide does not explain how to set up a service node, instead it explains for non-technical users how they can contribute to a service node which is run by a separate operator, allowing them to share in the rewards earned by that service node.
The first step is to find out if there are any service nodes which are "Awaiting Contribution", this occurs when a service node requires additional contributors to make up the 15,000 oxen requirement.
If you navigate to oxen.observer you can see on the front page a section titled "Service Nodes Awaiting Contributions" (Highlighted in Orange Below).
We are going to stake to the service node highlighted in green (a321e...)
Throughout this guide we will be using the Oxen "testnet" for demonstration purposes. This differs slightly to our mainnet in that you only need to contribute 100 oxen to set up a service node. Aside from this, the process is identical.
This section will explain some of the technical details contained in the above image and is optional, please feel free to skip to the next section which explains the GUI wallet usage if you please. In the above image there are 2 Service nodes that are awaiting contribution, the columns in the table are as follows:
Public Key: Service nodes are identified by a unique public key, this will be used later in the staking process and for finding the node at later dates. So you will need to write this down
Contributors: A maximum of 4 contributors are allowed to stake to a single service node. For the identified service node there is a single contributor so far (The operator who set up the node)
Operator Fee: The operator is allowed to charge a "fee" which is used to cover their server expenses. In this case the operator is looking to charge a 10% fee for running the node. This fee is market driven and we see a range of fees depending on the token price, hosting fees etc. For a ballpark figure the range is usually between 5%-15%. The calculation for how the fee affects contributors is as follows:
Each block that the service node creates will earn all contributors 16.5 oxen
The operator will take their fee of 10% = 1.65 oxen
The remaining balance 16.5 - 1.65 = 14.85 oxen will be distributed pro rata amongst all the contributors.
In this guide we will be contributing 75% of the total staked amount. This means we will be receiving 11.1375 oxen per block the node creates.
The operator who contributed 25% of the total staked amount will also receive 3.7125 oxen for their share. This is in addition to their fee so the operator will receive 5.3625 oxen in total.
Contributed: This keeps track of the total oxen staked so far by contributors. When this amount reaches 15,000 oxen the node will be considered fully staked and becomes an active service node that can earn rewards.
Open for Contribution: The remaining amount needed before the node is fully staked.
Min Contribution: As there is a maximum of 4 contributors to a service node there is a minimum amount to contribute enforced on the stakers. This formula is: Remaining Amount Open for Contribution / Slots left for stakers
In this case there is only 1 contribution so far, 3 slots out of 4 remaining. 75 oxen open for contribution divided by 3 = 25 oxen
This usually results in a minimum of about 25% of the total requirement (25% of 15,000 = 3,750). However if a person contributes over the minimum amount it means that later contributors have a lower minimum. So infrequently we see a minimum required amount of a few hundred oxen.
Expiry Date: Historically service nodes had an expiry date and operators were required to restake/restart the node. This has changed and now it is usual to run nodes infinitely with no expiry date.
Open up the GUI wallet and click on "Service Nodes"
When on the service nodes page, you will see the following:
There is a fair amount going on in this page. The areas identified by the green numbers above are:
Buttons to navigate the service nodes page (You will want to stay on the "Staking" tab for now).
My Stakes: Keeps track of nodes you have staked to and will be discussed below
Staking: Current page and what we are using to stake to another persons node
Registration: Used to set up a service node and is outside of the scope of this guide
Service Node Key: Here we enter in the the public key we identified from the oxen.observer page. We chose the key a321e... and have entered it in.
Amount: This needs to be above the minimum contribution and a maximum that will completely fill the service node. There are buttons on the right that conveniently calculate this for you
A list identical to the oxen.observer page is shown here. Clicking on the stake button on the right of the items will prefill the Service Node Key and Amount will be set to the minimum
We are deciding to fully stake the remaining amount to this service node, so have entered in 75 oxen (75+25 = 100 oxen required for testnet nodes, on mainnet this is 15,000).
When the fields are correct click on "Stake" (Highlighted with a green box above). You will be prompted with a confirmation.
After clicking Stake your wallet will send a transaction to the network. You should see a green notification that the staking transaction was sent successfully. This transaction will lock that amount so that you are unable to spend, but the funds still belong to you and are available to unlock (Which will be shown shortly). Navigating to the main page of the wallet will show the pending stake transaction.
The pending transaction once confirmed on the blockchain will transform into a "Stake Transaction"
Once the transaction has been confirmed you will be able to check the oxen.observer website for the service node and it will confirm that the service node is active. You can find this page by searching the Service Node Public Key in the search box at the top of the page.
Back in the wallet you will also be able to navigate to the "My Stakes" tab which will show the staked service node. Please note that this page is updated on wallet startup, so you will need to restart the wallet to see the changes after staking.
On this page you will see a complete list of staked nodes and how much you have contributed. On the right of each node you will see the option to unlock (Highlighted in red). When you wish to stop staking you will need to begin the unlock process, this takes 15 days on the mainnet so careful planning needs to be done to ensure you unlock early enough if you need access to the funds. Clicking unlock will prompt you with with a confirmation popup.
Please note that when you contribute to a node other users also have a vested interest in the node. Unlocking will force the other users to also unlock and the operator will need to restart the node staking process which many operators find frustrating. Frequent unlocking is rude. When unlocking the node will continue earning rewards until the point it is unlocked (15 days). Funds will also remain locked during this time. Once the 15 days have elapsed the funds will be unlocked and available to spend and the node will cease to earn rewards.
The My Stakes page will also show the node as unlocking and when visiting the oxen.observer website the service node page will also show the node as unlocking.
At this point you have all the skills that are necessary to stake to a service node and to unlock the stake when you wish to exit. Visit https://oxen.observer/ and start exploring the nodes that are awaiting contribution today!
The Oxen Wallet allows you to export a CSV of transactions that have occurred in the wallet. The process for both the GUI wallet and the CLI wallet are as follows:
The Oxen GUI wallet as of v1.6.0 supports the exporting of your transactions. After logging into your wallet:
Click on SETTINGS at the top right of the app
Click on Export Transfers
The wallet will then prompt you for a folder to save the CSV to. This defaults to a CSV directory within the Oxen folder (Same directory your wallet keys are stored) but you can edit this to any location.
Click Export and you will be prompted for your wallet password
You will then see a green notification at the bottom of the window if the export is successful. For example: “Transfers exported to /home/sean/Desktop/transfers.csv”
Note you will either need to be running a local daemon (oxend) or have a remote node that the CLI wallet can communicate with.
Navigate to the directory that the oxen-wallet-cli executable is stored in:
Run the oxen-wallet-cli:
If you are using a remote node instead of a local daemon you will need to add additional command line arguments here:
The wallet will ask you to enter the name of your wallet file. If you are coming from the GUI wallet these are stored in the following locations
Linux: ~/Oxen/wallets/MyWallet.keys
Windows: C:\Users<username>\Documents\Oxen\wallets
Mac: ~/Oxen/wallets/MyWallet.keys
These can alternatively be included as command line flags
Once the wallet has synced you will be able to call `export_transfers` which saves the CSV to the same location as where you ran the oxen-wallet-cli (Most likely the same location as the executable).
Background Information
The Ledger hardware wallet stores your private keys on-device so as to isolate your private keys from your PC (which can be at risk of viruses and other attacks). The use of a hardware wallet changes the way you interact with your software slightly.
The oxen-wallet-cli software usually creates 2 files which it uses for processing transactions. The files are named after your wallet name which you specify during startup.
After this initial step you will see the two files:
1) MyWallet – Large File ~15Mb
2) MyWallet.keys – Small File ~ 1.4Kb
The first file contains the saved state of the Oxen wallet. The wallet processes encrypted transactions on the blockchain and then records your unspent transactions here.
The second file contains your encrypted private keys.
When using the Ledger hardware wallet, the oxen-wallet-cli software will still create the first file to save the wallet state but the second file no longer contains your private keys. Instead, they will be saved securely on the hardware device (note: public keys and view keys, if exported, will still be saved here). This changes the process that oxen-wallet-cli will follow in order to sign a transaction.
Without a hardware wallet: oxen-wallet-cli will craft an unsigned transaction, then will reference the MyWallet.keys file to prepare a signed transaction which it will submit to the mempool and broadcast out to the Oxen network.
With a hardware wallet: oxen-wallet-cli will craft an unsigned transaction then submit it to the Ledger hardware wallet for signing. The Ledger hardware wallet will return a signed transaction to oxen-wallet-cli which the software will then submit to the network.
Before being able to generate an Oxen wallet on the ledger you will need to have initialized your Ledger and should have your 24 word mnemonic seed previously generated.
You will also need to have the Oxen App installed on your Ledger.
The first step is to connect the Ledger to your PC via the microUSB cable and run the Oxen Ledger App.
Next, ensure that your daemon (oxend
) is running with a fully synced blockchain (alternatively, you can connect oxen-wallet-cli to a remote node)
Navigate to the directory where oxen-wallet-cli is located (the following commands assume oxen-wallet-cli is located in the home directory and under a folder called oxen) and call the software using the “generate-from-device” flag
cd ~/oxen
./oxen-wallet-cli --generate-from-device <NEW_WALLET_NAME>
Replace <NEW_WALLET_NAME> with your desired wallet name. For instance if you want to name your wallet MyLedgerWallet you would use the following command:
./oxen-wallet-cli –generate-from-device MyLedgerWallet
The CLI will execute the command, then prompt you for a password to encrypt the wallet state information file mentioned above.
The Ledger device will ask you to confirm whether you want to export the private view key. This view key is used to search and decrypt the transactions in blockchain. Exporting this key to the software will enable oxen-wallet-cli to search the blockchain (rather than the Ledger device itself). The oxen-wallet-cli client will be able to search the blockchain significantly faster if you export the private view key. It should be noted that your funds cannot be compromised by this view key, but if an attacker was to obtain this key they could scan and identify your incoming transactions, which would be detrimental to your privacy.
Navigate using the left and right buttons on the Ledger to either the accept or reject screen and press both buttons simultaneously to confirm your choice. After confirming, the Ledger will then generate your wallet. Note this may take 5-10 minutes and the Ledger will not provide immediate feedback while doing so.
Next you will be prompted to enter the wallet restore height. This lets the wallet know that it can stop searching the blockchain for transactions prior to this block. If this is a new wallet then you can safely use the default [curr] by pressing Enter; if this is a wallet that has previously received transactions, then enter an appropriate restore height, or 0 to restore from the very start of the blockchain (a much slower process).
After the wallet has been generated, oxen-wallet-cli will start refreshing (scanning the blockchain for transactions). Wait until it has fully refreshed.
Congratulations, you can now use your Ledger wallet in conjunction with the Oxen CLI wallet!CLI
You only use the --generate-from-device on the single occasion when creating the wallet. Going forward, you use the CLI wallet as usual but select the wallet file corresponding to the Ledger wallet.
Steps to use:
Make sure your Ledger is plugged in and the Oxen app is running.
Open oxen-wallet-cli
Enter the wallet name of your Ledger Oxen wallet. This is the same as the name of the wallet state file mentioned above.
Enter the password to open the wallet.
Call oxen-wallet-cli from the same directory as the wallet file created above using the generate-from-device-flag
./oxen-wallet-cli
You will then be prompted to specify the wallet file name and enter the password. If you didn’t instruct your Ledger to always provide the view key, then your wallet will prompt you again for permission to provide it (you can change this setting later in the Settings within the Ledger app).
Afterwards, you will be able to enter commands into the wallet. This process is the same for both Ledger wallets and non-Ledger wallets, except that there will be an extra confirmation step on the Ledger before transactions can be submitted to the blockchain.
Enter the following command to transfer to another address:
transfer <DESTINATION_ADDRESS> <AMOUNT>
For example, transferring 50 Oxen to the following testnet address can be done via:
transfer T6SjALssDNvPZnTnV7vr459SX632c4X5qjLKfHfzvS32RPuhH3vnJmP9fyiD6ZiMu4XPk8ofH95mNRDg5bUPWkmq1LGAnyP3B 50
You will then be prompted to enter your password, and the Ledger device will start to process the transaction.
During this process, the Ledger will prompt you to confirm the following details of the transaction:
Fee
Recipient Address and Amount
After confirming the transaction on the Ledger wallet, the oxen-wallet-cli will also prompt you to confirm the transaction details. Typing ‘Yes’ to confirm will submit the transaction to the blockchain network
Congratulations, you have successfully transferred funds using the private keys saved securely on your Ledger.
Care should be taken when closing the wallet. If the Ledger is powered off incorrectly, there is a risk of data corruption. Follow these steps to close the app safely:
1) Shut down oxen-wallet-cli by typing “exit” and hitting Enter. The wallet will take a few moments to update the wallet cache file on disk.
2) Close the Oxen Ledger App
3) Unplug the Ledger device
This guide will walk you through using the Oxen Mobile wallet for the first time. This guide was created on an Android phone but the user experience of the Mobile wallet on iOS is identical.
We will discuss in detail the process of creating & using the wallet later in this guide. But a quick overview of the GUI wallet is as follows. The main wallet page looks like this:
This page displays:
1) Your wallet's available balance is shown front and centre in large text
2) Buttons in the middle for sending and receiving transactions
3) A list of historical transactions at the bottom
4) At the top we have the name of the wallet "TepidFlavor" which you will create when making the wallet
5) Your wallets synchronization status, in this photo the wallet is "Synchronized" which tells you how much of the blockchain your wallet has analysed
6) On the top right is a profile icon which allows you to configure the wallet, access settings, generate new wallets and stake to Oxen Service Nodes
7) The refresh icon on the right allows you to force refresh the blockchain and reconnect to the remote node if the wallet has synced incorrectly
The mobile wallet can be downloaded from Google Play Store under Oxen Wallet.
You can find this app via this link:
https://play.google.com/store/apps/details?id=io.oxen.wallet Please be mindful when downloading as the play store has been know to allow copycat apps designed to steal your crypto. The app developer is "Oxen Project" which is the same author as "Session" and "Loki Wallet" (Our old wallet app).
The iOS app can be found via this link: https://apps.apple.com/us/app/oxen-wallet-rangeproof/id1547745078
Congratulations on downloading the mobile wallet. The first time you open the app you will need to create your wallet, do this by clicking "Create new" to continue.
Your wallet is protected by a 4 or 6 digit PIN number. You will be required to enter this pin whenever you open the app and also when sending transactions. Enter a PIN you will remember.
The first thing the app asks is for a name of the new wallet. These are simply used to give a distinguishable name to identify the wallet. Choose something that is memorable because your wallet list can become unwieldy rather quickly when creating multiple wallets. For this reason using names such as: Wallet1, Wallet2, Wallet3 etc are not recommended. The app also provides a random default name (In this case "TepidFlavor").
In addition you will need to choose a language for the seed phrase generated in the next step. The most important part of the wallet creation process is the creation of your “Seed Phrase”. This is shown in the next step. Select your native language here to make the recording of your seed phrase easier.
Below you can see the app has now generated 25 words that are used to generate the private keys of your wallet.
Please note that these 25 seed words are by far the most important part of the wallet creation process. Write these somewhere safe! Don't lose them. If a malicious person gets access to these words they will be able to spend your funds. The Oxen team will NEVER ask you for your seed phrase and a person requesting them from you is likely a scammer trying to steal your funds.
You won’t need to regularly use these seed words. But if/when you need to recover your wallet or move the wallet to a different device then everything can be rebuilt using these 25 words.
After you have saved your seed phrase click "Next" to proceed.
At this point you now are brought to the wallet main page. When you first open the wallet the software needs to process blocks on the blockchain to check for transactions that belong to you. While the wallet is doing this you will see the status bar at the top stating how many blocks are remaining.
When the wallet is synchronising it is normal and expected that your transactions are not processed and therefore won't be shown in the app. Please wait until the wallet shows "SYNCHRONIZED" to continue.
When purchasing Oxen from an exchange or requesting funds from another person you will need to provide your wallet address. Your wallet address is a 95 character text starting with “L”. This is shown by clicking on the "Receive" button:
A QR code is also provided that can be read by other users mobile wallets. If you enter a number into the "Amount" input box this will modify the QR code so the mobile wallet reading the QR code knows how much should be paid in the transaction.
Clicking on the address string ("L8jFZ...VhS9o) will copy the address to your phones clipboard.
When receiving funds from an exchange there will generally be some processing time from the exchange (This time varies depending on the exchange) then a transfer will occur on the blockchain which your wallet will recognise.
The wallet scans the blockchain to find transfers that belong to you, when it finds one it will be added to the transaction list at the bottom. If the wallet is not detecting your transfers the most common reason that the wallet is not yet fully synced.
You can also click into the transaction to show more details.
Please note that your "Available Balance" will not update immediately. This is normal so don't worry, this is because the wallet enforces a 10 block (20 minute) waiting time before allowing you to spend recently received funds. The reasons for this are interesting and complicated but the TLDR is that as a privacy coin the wallet needs to be mindful of statistical attacks, and spend transactions that occur immediately after receiving funds are easily traceable, which reduces the privacy of all the transactions the blockchain (not just your own transactions).
After 10 blocks your available balance will update and you can then spend/stake your coins:
From the main app display click "Send" to bring up the following page:
To send funds you will need to obtain the address of the recipient. This will be a 95 character text string provided by the recipient. Usually you will copy and paste this address into the "Oxen address" text box, however you can also click on the QR code button to scan the address through the mobile phones camera.
You will also need to enter in the amount that is to be transferred. This can be specified in the "Oxen" text box which represents number of whole oxen to be transferred.
Alternatively you can enter the amount value in USD, which will automatically calculate the correct amount of oxen to transfer using current market rates. You only need to enter the amount into one field.
When sending transactions on the blockchain there is always a small fee charged to the sender. The wallet shows an estimate on this page (but will confirm the exact amount at a later point).
To proceed with the transaction slide the "Send Oxen" slider to the right. You will be asked to enter your PIN and the final details of the transaction will be displayed.
The final amounts will be shown and the exact fee displayed. To confirm the transaction and send to the network click "OK". After this point the app should display "Transaction Sent"
After this point your transaction will have been sent to the network. After the nodes confirm this transaction into the blockchain your transaction will then appear in the transaction list on the main display screen.
And that's it! You have successfully used the wallet to send and receive a transaction!
Using the Ledger hardware wallet with the Oxen GUI wallet is almost identical to the process with keys stored on your desktop. The two differences are:
There is a special process to create the wallet file.
When sending transactions the ledger device will prompt you to confirm the transaction.
Connect the hardware wallet to the PC and navigate to the oxen app.
The wallet needs to communicate with the Ledger and it must be on the Oxen dashboard page. This guide will demonstrate the process on a Ledger Nano S Plus. But both the Ledger Nano X and the Ledger Nano S will follow the same process.
From the Ledger app homepage (app selection) navigate to the Oxen app and press both buttons to select.
As the Oxen wallet app is currently being reviewed by the Ledger team you will first be prompted with a screen that reads “Pending Ledger review”. This screen will display for a few seconds and then allow you to progress by pressing both buttons at the same time.
You should now arrive on the Oxen dashboard. The divide will display “OXEN wallet” and a truncated string of the Oxen address. On this Ledger you can see that the Oxen Address is “LCYwfQr..XHS”. This address should also match the address displayed on the GUI wallet.
The device will need to be on this screen to work with the Oxen GUI wallet. All communications to the device happen via this page on the Oxen wallet app. If you are on any other page on your Ledger device, the GUI wallet will display an error message.
Setting up a hardware wallet file:
When you open the GUI wallet you will see the regular wallet select screen. We will select “Create New Wallet” from the dropdown menu which appears when clicking the + icon in the top right of the window.
The 1.8.0 version of the Oxen GUI wallet now has a checkbox on this page to confirm that the wallet will be a hardware wallet. Fill in the form with the new wallet name, password, check the hardware wallet box and click “Create Wallet”
You will then receive a prompt from the Ledger to “Export View Key” in order to create the wallet file on your desktop. Navigate to the “Always Export'' page by clicking the right button once, then click both buttons to accept.
Background on Exporting the View Key - Optional Technical Details on what just happened
One of the core functions of the wallet is to scan the blockchain which contains encrypted transactions. Each wallet has two keys that are used to:
1) Decrypt the encrypted transactions from the blockchain (View Key)
2) Craft transactions to spend funds in a transaction (Spend Key)
The wallet scans many transactions and processes a large amount of data to find the funds on the blockchain that belong to your wallet. This is an intensive computation that does take time on a regular computer. When using a hardware wallet the desktop does not have access to these keys, so we have two options to process the transaction:
Do the heavy computation on the small ledger wallet chip
Copy the View Key over to the desktop and let the bigger CPU handle this
There are drawbacks to both options. Doing the computation on the ledger is very slow. Exporting the view key is privacy reducing as it means if your desktop wallet is compromised it will be able to view your transactions (However it will not be able to make transactions).
Our recommendation is to export the view key and let the desktop process this calculation. The biggest benefit to having a hardware wallet is that a compromised computer will not be able to spend your funds so the tradeoff for processing the blockchain in a reasonable time is worth it in our opinion.
Continuing with the wallet creation
To access the hardware from now on, simply navigate through the wallet select page and you will see the new hardware wallet available under a heading called “Hardware wallets”. Clicking into this wallet will require the ledger device to be opened to the Oxen App main screen.
Navigate to the Send Transaction page on the wallet GUI
Create a transaction by filling in the address and amount fields of this page and then clicking “Send”
The hardware wallet will then begin processing the transaction. At first you will see the “Processsing TX” screen. This page may take some time as the ledger has to do some heavy calculations.
After this point the Ledger will confirm the transaction fee. Click the right button once to navigate to the “Accept” page and click both buttons to progress.
Next the wallet will confirm the amount and the recipient. Navigate right with the right button and the recipient should match what was entered into the GUI software page. Keep navigating right until the ledger displays the “Accept” page and click both buttons to progress
After this point the GUI wallet will prompt you to confirm send. Click “Send” to broadcast the transaction to the network.
The ledger will do some final processing and you will be rewarded with a green “Transaction Sent” notification in the GUI wallet.
Deregistration rules are used to manage the network in a decentralised way by having Oxen Service Nodes police each other's performance, ensuring all operational service nodes are up to date and performing adequately to maintain a healthy network.
Each Oxen Service Node can be in one of four states: awaiting, active, decommissioned or deregistered.
Active Oxen Service Nodes earn "credits" which are then used up during any periods where the service node goes offline (or otherwise stops meeting network requirements) to stop a deregistration from occuring. A new service node starts out with INITIAL_CREDIT
, and then builds up CREDIT_PER_DAY
for each day the service node remains active, up to a maximum of DECOMMISSION_MAX_CREDIT
.
Example:
If an Oxen Service Node stops sending uptime proofs, a quorum of service nodes will analyse whether the service node has built up enough credits (at least MINIMUM
). If so, instead of submitting a deregistration, the quorum instead submits a decommission. This removes the service node from the list of active service nodes, both for rewards and for any active network duties.
If the service node comes back online (i.e. starts sending the required performance proofs again) before its credits run out, a quorum will reinstate the service node using a recommission transaction, which adds the service node back to the bottom of the service node reward list, and resets the node's accumulated credits to 0. If the service node does not come back online within the required number of blocks (i.e. if the node does not come back online and begin performing as required before its credits are depleted) then a quorum will send a permanent deregistration transaction to the network, locking that node's stake for 30 days.
A testing quorum is a random set of 10 Oxen Service Nodes that are required to test a portion of the network for uptime proofs and service node IP changes. At each block, a new quorum is formed, and this quorum is required to test 50 service nodes or 1% of the network.
If 7 of the 10 service nodes in a quorum (a "supermajority") vote that a service node is malicious or not meeting the minimum requirements then they will create a State_Change
transaction to decommission or deregister the service node, or drop it to the bottom of the rewards list.
A state change transaction changes the state of an Oxen Service Node. Typically, state change transactions are only created when a quorum comes to a consensus about a given service node's activities or lack thereof.
The only state change transaction that can be created by anyone is the Register
transaction, which changes the state of a service node from awaiting
to active
.
This document explains how to stake via the Oxen GUI Wallet.
The latest version of the wallet can be downloaded .
Please keep in mind, one can only stake via an open pool with the GUI wallet.
Open the Oxen GUI Wallet, enter your password, and let it fully sync to the latest blockheight.
Click on the SERVICE NODE
button.
On this step you will need to enter the service node public key obtained from the node operator (or ) and the amount of Oxen you are contributing to the node.
This can be done automatically by clicking STAKE
on one of the listed Service Nodes awaiting contribution in the wallet interface.
Once that is filled out, simply hit the STAKE
button.
Please note, if you receive an error at this step you will need to click the
SWEEP ALL
before you can stake from your wallet.
Congratulations, you're now staked!
This guide will walk you through the complete process of setting up, staking, and running an Oxen Service Node. The guide targets non-experts, so even if you're new to Linux or the command line, you should be able to follow the text without any difficulty.
You can run the Oxen Service Node software on any device running a supported operating system, but for the purposes of this guide, we'll assume you will be setting up a Service Node on a remote Ubuntu or Debian server. If you're new to Linux or running servers in general, this is the most straightforward approach. If you're more experienced and would prefer to run your Service Node on a different operating system, you'll need to modify the syntax of some commands to suit your system of choice.
These are the current basic requirements for running a Service Node as of October 2021. They will almost certainly increase in the future as the technologies powered by the Oxen network grow in popularity, so keep an eye on the and join either our or for all the latest updates.
Spec | Requirement |
---|
Note: It is possible for an experienced system administrator to run a Service Node on a server running an operating system other than Ubuntu or Debian. However, this requires additional work to start up and manage the required services, and is beyond the scope of this guide.
A Service Node starts as a full node on the Oxen network.
The full node becomes a Service Node when the owner locks the required amount of $OXEN (see below) and submits a registration transaction.
Service Nodes:
Monitor other Service Nodes and vote on their performance
Choosing where to set up your Service Node is the first and most critical decision you will face in setting up and running your node. There are a number of factors to consider. Because you will be locking up funds as part of operating your Service Node, you will want to ensure, at a minimum, that your server meets the technical requirements given above.
Your aim is to provide a stable, reliable server with good network connectivity, so that data can be efficiently routed to and from your node. An underpowered or poorly connected node will have a poor response time and add latency to the network for all users whose traffic passes through it, resulting in a less than optimal experience.
Additionally, you should consider the following factors. The more weight you attach to these factors when deciding where to run your node, the more value you will provide to the network.
Here, you will see that some countries and network operators are currently overrepresented on the Service Node network. In other words, a relatively small number of countries and network operators account for the majority of the network. This is bad for decentralisation.
To be robust against disparate forms of attack, a distributed network must pursue diversity at multiple levels:
Geographical diversity: distribution across multiple, disparate regions to minimise the effect of natural disasters
Sociopolitical diversity: distribution across multiple countries and legal jurisdictions to minimise the effects of unrest, legislation, coercion and espionage
You can make a significant contribution to decentralisation and provide greater value to the network by taking the above factors into account when choosing where to run your node. Take care, however, not to compromise on the core requirements of a node when trying to satisfy these goals.
For this reason, we strongly recommend against running a Service Node from home. Most consumer internet connections have poor upstream bandwidth (Service Nodes require a high speed connection for both uploading and downloading data) and typically don't provide a static IP address, which is essential for a Service Node. Connection speed and support aside, transient power and network outages are a relatively common occurrence with consumer-grade connections and can easily disrupt home servers.
Typically, the simplest and cheapest way to host a server such as an Oxen Service Node is to lease a Virtual Private Server (VPS). There are literally hundreds of options when it comes to VPS providers, but some of the more commonly chosen companies and products are listed below.
In any case, do not just settle on the first provider you encounter. No two are alike. Do your own research and choose a provider that seems professional, reputable and fits your budget.
A good VPS provider will also allow you to monitor your machine's resource consumption, seamlessly upgrade to a more powerful server at a later date, remotely reboot the host if it becomes unresponsive, and even recover or rebuild the system using out-of-band access if, for example, a bad configuration change results in lost network access.
When selecting your VPS’ operating system, please choose the latest Ubuntu LTS release or latest Debian stable release (currently 22.04 and 12, respectively) if you want to be able to follow the steps below verbatim. If you feel more confident and/or wish to run your server on another Linux distribution, the commands in this guide will still apply, but may need to be modified to suit your chosen operating system. In most cases, beginners and experts alike will be best served by sticking closely to this guide.
Every provider has a slightly different way of issuing you access to your new VPS. Most will send an email with the IP address, root username, and a root password to the VPS.
To access your server, you will need an SSH client for your operating system. Because we’re on Windows today, we’ll download PuTTY. Mac users can also use PuTTY. If you’re a Linux user, you probably don’t need us to tell you where to get an SSH client.
To connect to your VPS, you'll need to paste the provided IP address into the SSH client’s “Host Name (or IP address)” input box and click the “Open” button. The Port number can usually just be left as 22
.
A terminal window will now appear, prompting you for your log-in details, username (root
) and password, as provided by your VPS provider. When entering your password, characters will not appear in the terminal. This is normal. Hit enter after typing or pasting your password, and you should be logged in to your VPS.
Note: After logging in for the first time, the VPS may prompt you for a new password for the root account. The terminal will require you to enter the new password twice before you can start running commands. If you aren't prompted for a new
root
password but want to change it anyway, typesudo passwd
. Choose something very secure!
Consoles don't quite work like the rest of your computer. Here are some basic tips for navigating your way around the command line!
Don't try copying something by using the usual Ctrl + C
hotkey! If you want to copy something, do so by highlighting text and then right clicking it and selecting Copy. Pasting works by right clicking a blank area in the console and selecting Paste.
If you want to kill a process or stop something from running, press Ctrl + C
. (This is why you shouldn't try copying something with this hotkey!)
You can always check the directory you are in by typing pwd,
and you can list its contents by typing ls
.
You can always return to your home directory by typing cd
and pressing Enter.
You can move into a given directory by typing cd <name>
or move back up one level by typing cd ..
.
PuTTY allows you to easily duplicate or restart a session by right clicking the top of the window. Handy if you’re trying to do a few things at once.
Next, update your package lists (the lists that tell your server which software is available for install or upgrade). The following command downloads package lists from their respective package repositories and "updates" them to get information on the newest versions of packages and their dependencies. It will do this for all repositories and PPAs.
You'll notice a bunch of package lists were downloaded. Once this is complete run the below command to fetch new versions of any packages that came preinstalled on the system.
You'll be prompted to authorise the use of disk space. Type y
and Enter to authorise.
If you are prompted during the upgrade that a new version of any file is available then click the up and down arrows until you are hovering over install the package maintainer’s version
and click enter.
Alright, good to go. Our server is now set up, up to date, and is not running as root. On to the fun part!
If you are using a firewall then ensure that the following ports are open/reachable
Port 22020 (storage server connectivity; requires both TCP and UDP)
Port 22021 (client to storage server)
Port 22022 (blockchain syncing)
Port 22025 (Service Node to Service Node)
Port 1090 (Lokinet router data; UDP only)
You only need to do this step the first time you want to set up the Oxen repository; when you've done it once, the repository will automatically update whenever you fetch new system updates.
To add the apt
repository, run the following commands.
This first command installs the public key used to sign the Oxen Service Node packages:
The second command tells apt
where to find the packages. Note: Replace <DISTRO>
with the appropriate value to match your operating system. If your VPS is running Ubuntu 22.04 as recommended for this guide, replace <DISTRO>
with jammy
.
Otherwise, to check your <DISTRO>
, run the following command: lsb_release -sc
Alternatively, your <DISTRO>
can be found by using the following list:
bookworm (Debian 12)
bullseye (Debian 11)
buster (Debian 10)
jammy (Ubuntu 22.04)
focal (Ubuntu 20.04)
bionic (Ubuntu 18.04)
We also have repositories for Debian testing (trixie
or testing
) and unstable (sid
or unstable
), and typically support the latest or upcoming Ubuntu non-LTS release (mantic
, as of writing). Note, however, that none of these distribution versions are recommended for production service nodes.
Then resync your package repositories with:
To install the software needed to run a Service Node, simply install the oxen-service-node
package:
This will detect your public IP (or allow you to enter it yourself) and automatically update the /etc/oxen/oxen.conf
configuration file with the necessary additional settings to run a Service Node.
Note: This process can take up to 6 hours for the blockchain to fully sync.
If you encounter an error during the syncing process due to a 15000 millisecond ping, you can run this command to fix it:
Alternatively, the blockchain can be typically be downloaded in a fraction of the time required to sync it via the network, using the following command:
oxend
If you run the oxend
command with an appended oxend command (note that sudo
is not required!), the oxend
command forwards this instruction to the running oxend
. So, for example, to get the current oxend
status you can run you would run:
To see the output log of your node you can run the following command:
This is useful to see if your node is syncing with the blockchain and to see other diagnostic messages that may come up from time to time. (Press Ctrl-C
to stop watching the log).
For a full list of supported commands run:
You can also get basic statistics (such as uptime proof and ping times) on the running daemons from the systemctl status
commands:
This section of the guide is split into two parts:
You'll need your wallet address to register your Service Node. Copy your primary address from the Oxen GUI wallet, or run the address
command from within the Oxen CLI wallet, and copy the output.
Note: Do not use subaddresses for staking. Subaddresses are currently unsupported for staking in the Oxen wallet.
To run a Service Node as the sole contributor, you'll need:
A fully synchronized, up-to-date Oxen daemon running on your Service Node
An Oxen wallet with at least 15,000 $OXEN in it (to meet the staking requirement to register your Service Node)
Log in (if not already logged in) to the VPS running the Service Node, then run the following command:
The daemon will output the current staking requirement and prompt you with an input to clarify whether you are an individual staker or you will be running a pool. Type y
and click enter, as you will be the sole staker.
The daemon will now prompt you for the operator's (your) Oxen address — this is the address saved in Step 5. Retrieve this address, copy it, then paste it into the terminal and press Enter.
The daemon will now ask for a final confirmation. If you agree with the information provided, type y
and click enter.
The daemon will output a command which looks similar to:
NOTE: You must run the command which your daemon outputs, and not the command shown above.
To stake and register your Service Node, open your Oxen GUI wallet (with a balance of at least 15,000 $OXEN). Navigate to the Service Nodes tab, then the Registration subsection. Paste the register_service_node
command from Step 5.1.1 above, and click Register Service Node.
If you're using the Oxen CLI wallet, simply paste the registration command directly into the CLI wallet prompt and hit Enter.
The Service Node staking requirement is fixed at 15,000 $OXEN. Service Nodes accept at most 10 contributions, meaning the minimum contribution to a Service Node is <Remaining Staking Requirement> ➗ <Number of Remaining Contributors>
.
When setting up reserved spots in a pooled Service Node, the node administrator (you) must ensure the reserved stake amounts each meet the minimum staking requirement; contributors then simply stake their reserved amounts.
The operator (you) is the individual who will be hosting the pool and running the server hosting the Service Node, thus incurring the operating expenses involved in running a node.
To be an operator, you'll need to have:
A server running a fully synchronized, up-to-date oxend
An Oxen wallet with at least 3750 $OXEN (to meet the minimum Service Node operator staking requirement)
1-3 other contributors who also have an Oxen wallet (either the CLI or GUI wallet) with enough $OXEN to meet their portion of the total stake
If the operator wants to reserve contribution spots for specific contributors, the operator will need the addresses of the contributors and the amounts the 1-3 contributors will stake.
If you have the above ready, we can now prepare the Service Node.
Log in (if not already logged in) to the VPS running the Service Node, then run the following command:
oxend
will prompt you to specify if you will contribute the entire stake. Because you're running a pooled Service Node, type n
and press Enter.
Next, oxend
will request input for your desired operator fee. This value, which can be between 0-100, represents the percentage of the reward the operator will receive before the reward is distributed to all shareholders (including you!). For example, if you want to set up a 10% operator cut, you would type 10
and press Enter.
For example, imagine a Service Node with 4 contributors, including the operator, all staking equal amounts (25%). If the operator specified a 10% fee at this step, they would automatically receive 10% of the Service Node rewards, and the remaining 90% would then be split equally between the operator and the other 3 contributors.
The terminal will now display the minimum reserve the operator can contribute, and request input for the amount (in Oxen) you, as the operator, wish to contribute. Type your desired <operator contribution>
and click return.
Once you've set your desired stake amount, you'll be prompted to either reserve spots for individuals that have already agreed to stake into the Service Node, or leave the pool open for anyone to contribute.
If you want to reserve spots for specific contributors, type y
at this prompt and click return.
The terminal will now prompt you for the number of additional contributors you've organised to stake into this Service Node. Type in the number of reserved contributors, not including yourself, and press Enter.
The daemon will now prompt you for the operator's (your) Oxen address — this is the address saved in Step 5. Retrieve this address, copy it, then paste it into the terminal and press Enter.
Next, you need to input the amount of Oxen each contributor will stake, and the Oxen Walled Address of the specific contributor(s).
NOTE: It is possible to reserve only some of the required total stake for specific contributors, while leaving the remaining staking amount open for other contributors.
The daemon will display a summary of the information you've entered. This is your chance for a final check over to make sure the correct information has been entered. To confirm the information is correct, type y
and press Enter.
If the operator wishes to leave their pool complete open to contributions they should type n
at the reservation prompt and type Enter. The terminal will prompt you to input your address. Once your address has been entered, the terminal will display the remaining portion that needs to be contributed by others. If you agree, click y
and hit return.
The daemon will display a summary of the information you've entered. This is your chance for a final check over to make sure the correct information has been entered. To confirm the information is correct, type y
and press Enter.
Regardless of which option (closed or open) you've gone with, the daemon will output a command which looks similar to:
NOTE: You must run the command which your daemon outputs, and not the command shown above.
Copy the whole line of text in your daemon and paste it into your notepad, as you'll need to run this command from within your Oxen GUI (or CLI) wallet.
You have 2 weeks from the moment of registering the Service Node to run the register_service_node
command, however it is advised to do it as soon as possible.
Before you disconnect from your VPS, run the following command:
This will output a bunch of information about your Service Node, but there's one part we're interested in at this stage: the long string of random letters and numbers after the characters SN:
. This string is your Service Node's public key, used to identify your Service Node on the list of registered and operational Service Nodes. Select and copy the public key (do not copy any of the surrounding information).
On your local machine, open your Oxen GUI or CLI wallet and make sure your wallet contains at least 3750 $OXEN to meet the Service Node staking requirement. Once you're in your wallet and have checked the balance, run the command which was provided above when you ran the prepare_registration
command. The wallet will prompt you to confirm your password, then the amount of $OXEN to stake. Confirm this by typing y
and clicking enter.
Once this command completes, your staking transaction will be sent to be included on the blockchain. It may take a few minutes for the transaction to be mined into a block; you can check the status using the following command:
Once the Service Node registration is received, you can send the <Service Node Public Key>
to your contributors, along with the amount of $OXEN they are required to stake.
At this point, you'll need to wait until all contributors have staked before the Service Node activates and becomes eligible to begin receiving rewards.
After you've staked to your Service Node (or after all contributors have staked, if you're running a shared node), you'll need to check if your Service Node's public key is on the list of Service Nodes which are operational on the network. This will prove that your Service Node is running, recognised, and eligible to receive rewards.
Connect to the VPS where the Service Node is running and run the following command to retrieve your Service Node's public key:
This will output a long string of letters and numbers: your Service Node's public key. This public key is used to identify your Service Node on the list of registered and operational Service Nodes. Select and copy the public key.
Service Nodes will continually receive block rewards indefinitely until a stake is unlocked or the Service Node becomes deregistered. To unlock your stake, simply open the Oxen GUI Wallet and navigate to the Service Nodes > My Stakes tab. You can then click Unlock for any stake you wish to unlock:
The Service Node will expire 15 days (10800 blocks) after the unlock is requested, and your staked $OXEN will then become unlocked after expiry.
For pooled nodes, any contributor can submit an unlock request. This will schedule the Service Node for expiration. All locked stakes in that Service Node will be unlocked 15 days (10800 blocks) after the unlock is requested. Once an unlock is requested, this process can not be undone or prolonged. Service Node participants will continue receiving rewards until the node expires.
Receiving a deregistration after participant(s) have already requested an unlock overrides the 15-day (10800-block) stake unlock time, and sets the unlock time to 30 days (21600 blocks).
When a new release is available, upgrading is as simple as syncing with the repository:
Then installing updates using:
Note that this will install both updated
oxend
packages and any available system updates (this is generally a good thing!).
During the upgrade, all instances of oxend
will be restarted if they are currently running in order to switch to the updated oxend
.
If for some reason you want to install only Oxen package upgrades but not other system package updates, then instead of the sudo apt upgrade
you can use:
We highly recommend setting up monitoring for your Service Node. This is as simple as calling on the services of our Telegram or Discord bot. Contact @OxenSNBot
on Telegram or OxenSNBot#5812
on Discord and type /start
or $help
respectively to get started.
You should immediately make a back-up of your Service Node's secret key. This will allow you to recover from a disaster or to migrate your node to a different network service provider, should that prove necessary in the future.
The command to reveal the secret key is:
And the command to restore it is:
Alternatively, you can use a tool like scp
to copy the file off-host for safekeeping.
Note that for older service nodes (installed before Oxen 8.x) the server will have two keys: the above, plus a legacy
/var/lib/oxen/key
. You must additionally back up and restore this legacy key to restore such a service node, using:to show the key, and if you need to restore it (note the "legacy" added to the command):
If you are planning on unlocking and re-registering an older node with two keys, it is recommended to remove the legacy
/var/lib/oxen/key
after the registration expires, restart the oxen/lokinet/storage server services, and then register using the new, single key: this will leave you with just one key to back up and restore. IMPORTANT: Never remove any keys on an active, registered service node!
Well done! Your Service Node is configured, operational, and will now begin receiving rewards.
If you have a Mnemonic Seed Phrase, restoring your wallet from it would probably be a good option. Otherwise, you can restore your wallet from private keys. You will need to have the following keys to proceed:
Wallet public address
Spend Key
View Key
the latest release of wallet CLI software for your desired operating system
Unzip oxen-[operating-system]-[platform]-[version].zip
file
Open a (Windows) or (Linux / OSX) and navigate to the wallet folder
Run wallet with --generate-from-keys
argument:
./oxen-wallet-cli --generate-from-keys [New Wallet Name]
Where [New Wallet Name]
is a new wallet name. You can enter any name here, use something memorable and meaningful.
On the next step, specify all 3 wallet keys, one by one:
Enter Standard address and press [Enter]
Enter Secret spend key and press [Enter]
Enter Secret view key and press [Enter]
Confirm password and press [Enter].
If you know the block height at which wallet was created or a first transaction was made, you can enter it here. Specifying a blockchain height will help to scan the wallet faster.
If you don't know a specific blockchain height, press [Enter] for scanning from block height 0.
For refresh process to start, you need to have your daemon running. Another option would be to use a remote node. For that, use the following command, replacing and with the host and port number of the remote node you are connecting to:
Once refresh is done, you can use your full functioning restored wallet. Your public wallet address will remain the same.
The following steps can be used to register and update ONS mappings in the CLI wallet. Note that you can access a detailed description of each command within the app, using “help <command_name>”.
Purchasing an ONS record in the CLI wallet uses the ons_buy_mapping
command. All arguments for the ons_buy_mapping
command are optional except for the <name>
and <value>
that the name maps to.
ons_buy_mapping [index=<N1>[,<N2>,…]] [<priority>] [owner=<value>] [backup_owner=<value>] <name> <value>
Example: Buy an ONS record that maps ‘KeeJef’ to a Session ID: 053 … 254. The wallet buying is the owner of the record:
Example: Buy an ONS record that maps ‘KeeJef’ to a Session ID: 053 … 254. The wallet buying the mapping is the owner of the record, but specifies a backup owner who will also be authorised to update the record:
Example: Buy an ONS record that maps ‘KeeJef’ to a Session ID: 053…254. You buy on behalf of another wallet T6UD8...ppir and specify another backup wallet:
Updating an ONS record in the CLI wallet uses the ons_update_mapping
command. All arguments for the ons_update_mapping
command are optional except the name of the record to update, and at least one field of the record to update (owner, backup_owner, or value). The [signature] argument is for deferring updates to the record, and is explained in detail in the next section.
ons_update_mapping [owner=<value>] [backup_owner=<value>] [value=<ons_value>] [signature=<hex_signature>] <name>
Example: Updating the owner of the record (essentially transferring ownership — after changing ownership, you will no longer be authorised to update the record):
Note: At this time you can only update Session ID mappings, you cannot yet add a wallet address mapping to your name — this will require additional changes which will be implemented at a later date.
Example: Update all fields of the mapping.
In this scenario, you have an ONS record that you wish to update, and you’re able to coordinate with the wallet owning the record. The wallet that owns the record can execute this command to generate a signature.
ons_make_update_mapping_signature [owner=<value>] [backup_owner=<value>] [value=<ons_value>] <name>
Example: User transfers ownership of a record to another person T6TEJ…t3x with the value 058c…c08. The original owner generates a signature.
The generated signature:
On the wallet to execute, the arguments must match the arguments specified in the ons_make_update_mapping_signature
with the added signature argument:
A directory of guides for setting up and maintaining your Oxen Service Node.
Guide | Outline |
---|
This is a list of JSON2.0 RPC calls to be used with Oxen Service Nodes, along with examples of each.
Get the quorum state which is the list of public keys of the nodes who are voting, and the list of public keys of the nodes who are being tested.
Testnet Example
Result
Nodes have been omitted with “...” for brevity in nodes_to_test and quorum_nodes.
Inputs
Int height
The height to query the quorum state for
Outputs
String[] nodes_to_test
An array of public keys identifying service nodes which are being tested for the queried height.
String[] quorum_state
An array of public keys identifying service nodes which are responsible for voting on the queried height.
Get the required amount of $OXEN to become an Oxen Service Node at the queried height. For stagenet and testnet values, ensure the daemon is started with the --stagenet or --testnet flags respectively.
Testnet Example
Result
Inputs
Int height
The height to query the staking requirement for
Outputs
Uint64 staking_requirement
The staking requirement in Oxen atomic units for the queried height
Get the service node public key of the queried daemon. The daemon must be started in --service-node mode otherwise this RPC command will fail.
Testnet Example
Result
Inputs
N/A
Outputs
String service_node_pubkey
The public key identifying the queried service node
get_service_nodes
Get the metadata currently associated with the queried service node public keys such as, registration height and contributors, etc. If no public key is specified, this returns all the metadata for every service node the queried daemon currently knows about.
Testnet Example
Result
Inputs
String[] service_node_pubkeys
An array of service node public keys in strings that you wish to query metadata for. If an empty array is given, this RPC command returns all service nodes it knows about.
Outputs
Entry[] service_node_states
The array of metadata for the queried service node(s)
String service_node_pubkey
The queried service node’s identifying public key
Uint64 registration_height
The height at which the registration transaction arrived on the blockchain
Uint64 last_reward_block_height
The last block height this service node received a reward. Rewards are sent to service nodes whom have been waiting longest since their last reward and are then sent to the back of the queue.
Uint64 last_reward_transaction_index
The position in the queue to receive a reward for the service nodes grouped in the last_reward_block_height.
Uint64 last_uptime_proof
Unix epoch timestamp of the last time this daemon has received a ping from the queried service node.
Contribution[] contributors
An array consisting of all the addresses that have contributed to the queried service node.
Uint64 Contribution.amount
The amount of $OXEN in atomic units the contributor has staked.
Uint64 Contribution.reserved
The amount of $OXEN in atomic units the contributor has reserved and must fulfill to completely contribute their part to the service node. Amount is equal to reserved once the contributor has fully contributed their part.
String Contribution.address
The $OXEN address that funds must come from to fulfill the contribution requirement.
Uint64 total_contributed
The total $OXEN currently contributed going towards the staking requirement.
Uint64 total_reserved
The total $OXEN that has been reserved by all contributors. The remaining $OXEN is open for other contributors to increase their stake towards the service node.
Uint64 portions_for_operator
The operator cut expressed as a value from 0 -> STAKING_PORTIONS (defined in oxen/src/cryptonote_config.h) which is the fee taken from the service node reward and given to the operator address before rewards are distributed to the contributors.
Uint64 operator_address
The wallet address which is the primary owner of the service node and also the address which the operator cut is sent to.
This is a list of the oxend daemon RPC calls, their inputs and outputs, and examples of each.
Many RPC calls use the daemon's JSON RPC interface while others use their own interfaces, as demonstrated below.
Note: "atomic units" refer to the smallest fraction of 1 $OXEN according to the oxend implementation. 1 $OXEN = 1e12 atomic units.
The majority of oxend RPC calls use the daemon's json_rpc
interface to request various bits of information. These methods all follow a similar structure, for example:
Some methods include parameters, while others do not. Examples of each JSON RPC method follow.
Look up how many blocks are in the longest chain known to the node.
Alias: getblockcount.
Inputs: None.
Outputs:
count - unsigned int; Number of blocks in longest chain seen by the node.
status - string; General RPC error code. "OK" means everything looks good.
Example:
Look up a block's hash by its height.
Alias: on_getblockhash.
Inputs:
block height (int array of length 1)
Outputs:
block hash (string)
Example:
Get a block template on which mining a new block.
Alias: getblocktemplate.
Inputs:
wallet_address - string; Address of wallet to receive coinbase transactions if block is successfully mined.
reserve_size - unsigned int; Reserve size.
Outputs:
blocktemplate_blob - string; Blob on which to try to mine a new block.
blockhashing_blob - string; Blob on which to try to find a valid nonce.
difficulty - unsigned int; Difficulty of next block.
expected_reward - unsigned int; Coinbase reward expected to be received if block is successfully mined.
height - unsigned int; Height on which to mine.
prev_hash - string; Hash of the most recent block on which to mine the next block.
reserved_offset - unsigned int; Reserved offset.
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Example:
Submit a mined block to the network.
Alias: submitblock.
Inputs:
Outputs:
status - string; Block submit status.
In this example, a block blob which has not been mined is submitted:
Block header information for the most recent block is easily retrieved with this method. No inputs are needed.
Alias: getlastblockheader.
Inputs: None.
Outputs:
block_header - A structure containing block header information.
block_size - unsigned int; The block size in bytes.
depth - unsigned int; The number of blocks succeeding this block on the blockchain. A larger number means an older block.
difficulty - unsigned int; The strength of the Oxen network
hash - string; The hash of this block.
height - unsigned int; The number of blocks preceding this block on the blockchain.
major_version - unsigned int; The major version of the Oxen protocol at this block height.
minor_version - unsigned int; The minor version of the Oxen protocol at this block height.
nonce - unsigned int; a cryptographic random one-time number used in mining a $OXEN block.
num_txes - unsigned int; Number of transactions in the block, not counting the coinbase tx.
orphan_status - boolean; Usually false
. If true
, this block is not part of the longest chain.
prev_hash - string; The hash of the block immediately preceding this block in the chain.
reward - unsigned int; The amount of new generated in this block and rewarded to the miner. Note: 1 $OXEN = 1e12 atomic units.
timestamp - unsigned int; The unix time at which the block was recorded into the blockchain.
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
In this example, the most recent block (1562023 at the time) is returned:
Block header information can be retrieved using either a block's hash or height. This method includes a block's hash as an input parameter to retrieve basic information about the block.
Alias: getblockheaderbyhash.
Inputs:
hash - string; The block's sha256 hash.
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
In this example, block 912345 is looked up by its hash:
Alias: getblockheaderbyheight.
Inputs:
height - unsigned int; The block's height.
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
In this example, block 912345 is looked up by its height (notice that the returned information is the same as in the previous example):
Alias: getblockheadersrange.
Inputs:
start_height - unsigned int; The starting block's height.
end_height - unsigned int; The ending block's height.
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
In this example, blocks range from height 1545999 to 1546000 is looked up (notice that the returned informations are ascending order and that it is at the April 2018 network upgrade time):
Full block information can be retrieved by either block height or hash, like with the above block header calls. For full block information, both lookups use the same method, but with different input parameters.
Alias: getblock.
Inputs (pick one of the following):
height - unsigned int; The block's height.
hash - string; The block's hash.
Outputs:
blob - string; Hexadecimal blob of block information.
json - json string; JSON formatted block details:
major_version - Same as in block header.
minor_version - Same as in block header.
timestamp - Same as in block header.
prev_id - Same as prev_hash
in block header.
nonce - Same as in block header.
miner_tx - Miner transaction information
version - Transaction version number.
unlock_time - The block height when the coinbase transaction becomes spendable.
vin - List of transaction inputs:
gen - Miner txs are coinbase txs, or "gen".
height - This block height, a.k.a. when the coinbase is generated.
vout - List of transaction outputs. Each output contains:
amount - The amount of the output, in atomic units.
target -
key -
extra - Usually called the "transaction ID" but can be used to include any random 32 byte/64 character hex string.
signatures - Contain signatures of tx signers. Coinbased txs do not have signatures.
tx_hashes - List of hashes of non-coinbase transactions in the block. If there are no other transactions, this will be an empty list.
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Look up by height:
In the following example, block 912345 is looked up by its height. Note that block 912345 does not have any non-coinbase transactions. (See the next example for a block with extra transactions):
Look up by hash:
In the following example, block 993056 is looked up by its hash. Note that block 993056 has 3 non-coinbase transactions:
Retrieve information about incoming and outgoing connections to your node.
Alias: None.
Inputs: None.
Outputs:
connections - List of all connections and their info:
address - string; The peer's address, actually IPv4 & port
avg_download - unsigned int; Average bytes of data downloaded by node.
avg_upload - unsigned int; Average bytes of data uploaded by node.
connection_id - string; The connection ID
current_download - unsigned int; Current bytes downloaded by node.
current_upload - unsigned int; Current bytes uploaded by node.
height- unsigned int; The peer height
host - string; The peer host
incoming - boolean; Is the node getting information from your node?
ip - string; The node's IP address.
live_time - unsigned int
local_ip - boolean
localhost - boolean
peer_id - string; The node's ID on the network.
port - string; The port that the node is using to connect to the network.
recv_count - unsigned int
recv_idle_time - unsigned int
send_count - unsigned int
send_idle_time - unsigned int
state - string
support_flags - unsigned int
Following is an example of get_connections
and it's return:
Retrieve general information about the state of your node and the network.
Alias:
/get_info
/getinfo
Inputs: None.
Outputs:
alt_blocks_count - unsigned int; Number of alternative blocks to main chain.
block_size_limit - unsigned int; Maximum allowed block size
block_size_median - unsigned int; Median block size of latest 100 blocks
cumulative_difficulty - unsigned int; Cumulative difficulty of all blocks in the blockchain.
difficulty - unsigned int; Network difficulty (analogous to the strength of the network)
free_space - unsigned int; Available disk space on the node.
grey_peerlist_size - unsigned int; Grey Peerlist Size
height - unsigned int; Current length of longest chain known to daemon.
height_without_bootstrap - unsigned int; Current length of the local chain of the daemon.
incoming_connections_count - unsigned int; Number of peers connected to and pulling from your node.
mainnet - boolean; States if the node is on the mainnet (true
) or not (false
).
offline - boolean; States if the node is offline (true
) or online (false
).
outgoing_connections_count - unsigned int; Number of peers that you are connected to and getting information from.
rpc_connections_count - unsigned int; Number of RPC client connected to the daemon (Including this RPC request).
stagenet - boolean; States if the node is on the stagenet (true
) or not (false
).
start_time - unsigned int; Start time of the daemon, as UNIX time.
status - string; General RPC error code. "OK" means everything looks good.
target - unsigned int; Current target for next proof of work.
target_height - unsigned int; The height of the next block in the chain.
testnet - boolean; States if the node is on the testnet (true
) or not (false
).
top_block_hash - string; Hash of the highest block in the chain.
tx_count - unsigned int; Total number of non-coinbase transaction in the chain.
tx_pool_size - unsigned int; Number of transactions that have been broadcast but not included in a block.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
was_bootstrap_ever_used - boolean; States if a bootstrap node has ever been used since the daemon started.
white_peerlist_size - unsigned int; White Peerlist Size
Following is an example get_info
call and its return:
Look up information regarding hard fork voting and readiness.
Alias: None.
Inputs: None.
Outputs:
earliest_height - unsigned int; Block height at which hard fork would be enabled if voted in.
enabled - boolean; Tells if hard fork is enforced.
state - unsigned int; Current hard fork state: 0 (There is likely a hard fork), 1 (An update is needed to fork properly), or 2 (Everything looks good).
status - string; General RPC error code. "OK" means everything looks good.
threshold - unsigned int; Minimum percent of votes to trigger hard fork. Default is 80.
version - unsigned int; The major block version for the fork.
votes - unsigned int; Number of votes towards hard fork.
voting - unsigned int; Hard fork voting status.
window - unsigned int; Number of blocks over which current votes are cast. Default is 10080 blocks.
Example:
Ban another node by IP.
Alias: None.
Inputs:
bans - A list of nodes to ban:
host - string; Host to ban (IP in A.B.C.D form - will support I2P address in the future).
ip - unsigned int; IP address to ban, in Int format.
ban - boolean; Set true
to ban.
seconds - unsigned int; Number of seconds to ban node.
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
Examples:
banning by host
In the following example, host is banned with its IP address string-formatted as A.B.C.D:
banning by ip
In the following example, integer-formatted IP is banned:
Get list of banned IPs.
Alias: None.
Inputs: None.
Outputs:
bans - List of banned nodes:
host - string; Banned host (IP in A.B.C.D form).
ip - unsigned int; Banned IP address, in Int format.
seconds - unsigned int; Local Unix time that IP is banned until.
status - string; General RPC error code. "OK" means everything looks good.
Example:
Flush tx ids from transaction pool
Alias: None.
Inputs:
txids - array of strings; Optional, list of transactions IDs to flush from pool (all tx ids flushed if empty).
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
Example:
Get a histogram of output amounts. For all amounts (possibly filtered by parameters), gives the number of outputs on the chain for that amount. RingCT outputs counts as 0 amount.
Inputs:
amounts - list of unsigned int
min_count - unsigned int
max_count - unsigned int
unlocked - boolean
recent_cutoff - unsigned int
Outputs:
histogram - list of histogram entries, in the following structure:
amount - unsigned int; Output amount in atomic units
total_instances - unsigned int;
unlocked_instances - unsigned int;
recent_instances - unsigned int;
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Example:
Get the coinbase ammount and the fees ammount for n last blocks starting at particular height
Alias: None.
Inputs:
height - unsigned int; Block height from which getting the amounts
count - unsigned int; number of blocks to include in the sum
Outputs:
emission_amount - unsigned int; amount of coinbase reward in atomic units
fee_amount - unsigned int; amount of fees in atomic units
status - string; General RPC error code. "OK" means everything looks good.
Example:
Give the node current version
Alias: None.
Inputs: None.
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
version - unsigned int;
Example:
Gives an estimation on fees per kB.
Alias: None.
Inputs:
grace_blocks - unsigned int; Optional
Outputs:
fee - unsigned int; Amount of fees estimated per kB in atomic units
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Example:
Display alternative chains seen by the node.
Alias: None.
Inputs: None.
Outputs:
chains - array of chains, the following structure:
block_hash - string; the block hash of the first diverging block of this alternative chain.
difficulty - unsigned int; the cumulative difficulty of all blocks in the alternative chain.
height - unsigned int; the block height of the first diverging block of this alternative chain.
length - unsigned int; the length in blocks of this alternative chain, after divergence.
status - string; General RPC error code. "OK" means everything looks good.
Example:
Relay a list of transaction IDs.
Alias: None.
Inputs:
txids - array of string; list of transaction IDs to relay
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
Example:
Get synchronisation informations
Alias: None.
Inputs: None.
Outputs:
height - unsigned int;
peers - array of peer structure, defined as follows:
spans - array of span structure, defined as follows (optional, absent if node is fully synced):
connection_id - string; Id of connection
nblocks - unsigned int; number of blocks in that span
rate - unsigned int; connection rate
remote_address - string; peer address the node is downloading (or has downloaded) than span from
size - unsigned int; total number of bytes in that span's blocks (including txes)
speed - unsigned int; connection speed
start_block_height - unsigned int; block height of the first block in that span
status - string; General RPC error code. "OK" means everything looks good.
target_height - unsigned int; target height the node is syncing from (optional, absent if node is fully synced)
Example:
Get all transaction pool backlog
Alias: None.
Inputs: None.
Outputs:
backlog: array of structures tx_backlog_entry (in binary form):
blob_size - unsigned int (in binary form)
fee - unsigned int (in binary form)
time_in_pool - unsigned int (in binary form)
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Example:
Alias: None.
Inputs:
amounts - array of unsigned int; amounts to look for
cumulative - boolean; (optional, default is false
) States if the result should be cumulative (true
) or not (false
)
from_height - unsigned int; (optional, default is 0) starting height to check from
to_height - unsigned int; (optional, default is 0) ending height to check up to
Outputs:
distributions - array of structure distribution as follows:
amount - unsigned int
base - unsigned int
distribution - array of unsigned int
start_height - unsigned int
status - string; General RPC error code. "OK" means everything looks good.
Example:
Not all daemon RPC calls use the JSON_RPC interface. This section gives examples of these calls.
The data structure for these calls is different than the JSON RPC calls. Whereas the JSON RPC methods were called using the /json_rpc
extension and specifying a method, these methods are called at their own extensions. For example:
For calls that end with .bin, the data is exchanged in the form of binary, serialized objects, as defined in the Core RPC Server.
Get the node's current height.
Alias: /getheight.
Inputs: None.
Outputs:
height - unsigned int; Current length of longest chain known to daemon.
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Get all blocks info. Binary request.
Alias: /getblocks.bin.
Inputs:
block_ids - binary array of hashes; first 10 blocks id goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block
start_height - unsigned int
prune - boolean
Outputs:
blocks - array of block complete entries
current_height - unsigned int
output_indices - structure as follows:
indices - array of tx output indices, structure as follows:
indices - array of unsigned int
start_height - unsigned int
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Get blocks by height. Binary request.
Alias: /getblocks_by_height.bin.
Inputs:
heights - array of unsigned int; list of block heights
Outputs:
blocks - array of block complete entries
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Get hashes. Binary request.
Alias: /gethashes.bin.
Inputs:
block_ids - binary array of hashes; first 10 blocks id goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block
start_height - unsigned int
Outputs:
current_height - unsigned int
m_block_ids - binary array of hashes; see block_ids above.
start_height - unsigned int
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Get global outputs of transactions. Binary request.
Alias: None.
Inputs:
txid - binary txid
Outputs:
o_indexes - array of unsigned int; List of output indexes
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Get outputs. Binary request.
Alias: None.
Inputs:
outputs - array of structure get_outputs_out as follows:
amount - unsigned int;
index - unsigned int;
Outputs:
outs - array of structure outkey as follows:
amount - unsigned int;
height - unsigned int; block height of the output
key - the public key of the output
mask
txid - transaction id
unlocked - boolean; States if output is locked (false
) or not (true
)
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Look up one or more transactions by hash.
Alias: /gettransactions.
Inputs:
txs_hashes - string list; List of transaction hashes to look up.
decode_as_json - boolean; Optional (false
by default). If set true
, the returned transaction information will be decoded rather than binary.
prune - boolean; Optional (false
by default).
Outputs:
missed_tx - array of strings. (Optional - returned if not empty) Transaction hashes that could not be found.
status - General RPC error code. "OK" means everything looks good.
txs - array of structure entry as follows:
as_hex - string; Full transaction information as a hex string.
as_json - json string; List of transaction info:
version - Transaction version
unlock_time - If not 0, this tells when a transaction output is spendable.
vin - List of inputs into transaction:
key - The public key of the previous output spent in this transaction.
amount - The amount of the input, in atomic units.
key_offsets - A list of integer offets to the input.
k_image - The key image for the given input
vout - List of outputs from transaction:
amount - Amount of transaction output, in atomic units.
target - Output destination information:
key - The stealth public key of the receiver. Whoever owns the private key associated with this key controls this transaction output.
extra - Usually called the "payment ID" but can be used to include any random 32 bytes.
signatures - List of signatures used in ring signature to hide the true origin of the transaction.
block_height - unsigned int; block height including the transaction
block_timestamp - unsigned int; Unix time at chich the block has been added to the blockchain
double_spend_seen - boolean; States if the transaction is a double-spend (true
) or not (false
)
in_pool - boolean; States if the transaction is in pool (true
) or included in a block (false
)
output_indices - array of unsigned int; transaction indexes
tx_hash - string; transaction hash
txs_as_hex - string; Full transaction information as a hex string (old compatibility parameter)
txs_as_json - json string; (Optional - returned if set in inputs. Old compatibility parameter) List of transaction as in as_json above:
Example 1: Return transaction information in binary format.
Example 2: Decode returned transaction information in JSON format. Note: the "vin", "vout" and "signatures" list have been truncated in the displayed return for space considerations.
Example 3: Returned a missed (unexisting) transaction.
Get the known blocks hashes which are not on the main chain.
Alias: None.
Inputs: None
Outputs:
blks_hashes - array of strings; list of alternative blocks hashes to main chain
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Example:
Check if outputs have been spent using the key image associated with the output.
Alias: None.
Inputs:
key_images - string list; List of key image hex strings to check.
Outputs:
spent_status - unsigned int list; List of statuses for each image checked. Statuses are follows: 0 = unspent, 1 = spent in blockchain, 2 = spent in transaction pool
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Example:
Broadcast a raw transaction to the network.
Alias: /sendrawtransaction.
Inputs:
tx_as_hex - string; Full transaction information as hexidecimal string.
do_not_relay - boolean; Stop relaying transaction to other nodes (default is false
).
Outputs:
double_spend - boolean; Transaction is a double spend (true
) or not (false
).
fee_too_low - boolean; Fee is too low (true
) or OK (false
).
invalid_input - boolean; Input is invalid (true
) or valid (false
).
invalid_output - boolean; Output is invalid (true
) or valid (false
).
low_mixin - boolean; Mixin count is too low (true
) or OK (false
).
not_rct - boolean; Transaction is a standard ring transaction (true
) or a ring confidential transaction (false
).
not_relayed - boolean; Transaction was not relayed (true
) or relayed (false
).
overspend - boolean; Transaction uses more money than available (true
) or not (false
).
reason - string; Additional information. Currently empty or "Not relayed" if transaction was accepted but not relayed.
status - string; General RPC error code. "OK" means everything looks good. Any other value means that something went wrong.
too_big - boolean; Transaction size is too big (true
) or OK (false
).
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Example (No return information included here.):
Save the blockchain. The blockchain does not need saving and is always saved when modified, however it does a sync to flush the filesystem cache onto the disk for safety purposes against Operating System or Harware crashes.
Alias: None.
Inputs: None.
Outputs:
status - string; General RPC error code. "OK" means everything looks good. Any other value means that something went wrong.
Example:
Get the known peers list.
Alias: None.
Inputs: None.
Outputs:
gray_list - array of offline peer structure as follows:
host - unsigned int; IP address in integer format
id - string; Peer id
ip - unsigned int; IP address in integer format
last_seen - unsigned int; unix time at which the peer has been seen for the last time
port - unsigned int; TCP port the peer is using to connect to Oxen network.
status - string; General RPC error code. "OK" means everything looks good. Any other value means that something went wrong.
white_list - array of online peer structure, as above.
Example (truncated lists):
Set the log hash rate display mode.
Alias: None.
Inputs:
visible - boolean; States if hash rate logs should be visible (true
) or hidden (false
)
Outputs:
status - string; General RPC error code. "OK" means everything looks good. Any other value means that something went wrong.
Example while mining:
Error while not mining:
Set the daemon log level. By default, log level is set to 0
.
Alias: None.
Inputs:
level - integer; daemon log level to set from 0
(less verbose) to 4
(most verbose)
Outputs:
status - string; General RPC error code. "OK" means everything looks good. Any other value means that something went wrong.
Example:
Set the daemon log categories. Categories are represented as a comma separated list of <Category>:<level>
(similarly to syslog standard <Facility>:<Severity-level>
), where:
Category is one of the following:
* - All facilities
default
net
net.http
net.p2p
logging
net.throttle
blockchain.db
blockchain.db.lmdb
bcutil
checkpoints
net.dns
net.dl
i18n
perf
stacktrace
updates
account
cn
difficulty
hardfork
miner
blockchain
txpool
cn.block_queue
net.cn
daemon
debugtools.deserialize
debugtools.objectsizes
device.ledger
wallet.gen_multisig
multisig
bulletproofs
ringct
daemon.rpc
wallet.simplewallet
WalletAPI
wallet.ringdb
wallet.wallet2
wallet.rpc
tests.core
Level is one of the following:
FATAL - higher level
ERROR
WARNING
INFO
DEBUG
TRACE - lower level A level automatically includes higher level. By default, categories are set to *:WARNING,net:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO,logging:INFO,msgwriter:INFO
. Setting the categories to "" prevent any logs to be outputed.
Alias: None.
Inputs:
categories - string; Optional, daemon log categories to enable
Outputs:
categories - string; daemon log enabled categories
status - string; General RPC error code. "OK" means everything looks good. Any other value means that something went wrong.
Example to set all facilities to Security Level Info
:
Example without input to set the default categories:
Show information about valid transactions seen by the node but not yet mined into a block, as well as spent key image information for the txpool in the node's memory.
Alias: None.
Inputs: None.
Outputs:
spent_key_images - List of spent output key images:
id_hash - string; Key image.
txs_hashes - string list; tx hashes of the txes (usually one) spending that key image.
status - string; General RPC error code. "OK" means everything looks good.
transactions - List of transactions in the mempool are not in a block on the main chain at the moment:
blob_size - unsigned int; The size of the full transaction blob.
double_spend_seen - boolean; States if this transaction has been seen as double spend.
do_not_relay; boolean; States if this transaction should not be relayed
fee - unsigned int; The amount of the mining fee included in the transaction, in atomic units.
id_hash - string; The transaction ID hash.
kept_by_block - boolean; States if the tx was included in a block at least once (true
) or not (false
).
last_failed_height - unsigned int; If the transaction validation has previously failed, this tells at what height that occured.
last_failed_id_hash - string; Like the previous, this tells the previous transaction ID hash.
last_relayed_time - unsigned int; Last unix time at which the transaction has been relayed.
max_used_block_height - unsigned int; Tells the height of the most recent block with an output used in this transaction.
max_used_block_hash - string; Tells the hash of the most recent block with an output used in this transaction.
receive_time - unsigned int; The Unix time that the transaction was first seen on the network by the node.
relayed - boolean; States if this transaction has been relayed
tx_blob - unsigned int; Hexadecimal blob represnting the transaction.
tx_json - json string; JSON structure of all information in the transaction:
version - Transaction version
unlock_time - If not 0, this tells when a transaction output is spendable.
vin - List of inputs into transaction:
key - The public key of the previous output spent in this transaction.
amount - The amount of the input, in atomic units.
key_offsets - A list of integer offets to the input.
k_image - The key image for the given input
vout - List of outputs from transaction:
amount - Amount of transaction output, in atomic units.
target - Output destination information:
key - The stealth public key of the receiver. Whoever owns the private key associated with this key controls this transaction output.
extra - Usually called the "transaction ID" but can be used to include any random 32 bytes.
rct_signatures - Ring signatures:
type
txnFee
ecdhInfo - array of Diffie Helman Elipctic curves structures as follows:
mask - String
amount - String
outPk
rctsig_prunable
rangeSigs - array of structures as follows:
asig
Ci
MGs - array of structures as follows:
ss - array of arrays of two strings.
cc - String
Example (Note: Some lists in the returned information have been truncated for display reasons):
Get hashes from transaction pool. Binary request.
Alias: None.
Inputs: None.
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
tx_hashes - binary array of transaction hashes.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Example:
Get the transaction pool statistics.
Alias: None.
Inputs: None.
Outputs:
pool_stats - Structure as follows:
bytes_max - unsigned int; Max transaction size in pool
bytes_med - unsigned int; Median transaction size in pool
bytes_min - unsigned int; Min transaction size in pool
bytes_total - unsigned int; total size of all transactions in pool
histo - structure txpool_histo as follows:
txs - unsigned int; number of transactions
bytes - unsigned int; size in bytes.
histo_98pc unsigned int; the time 98% of txes are "younger" than
num_10m unsigned int; number of transactions in pool for more than 10 minutes
num_double_spends unsigned int; number of double spend transactions
num_failing unsigned int; number of failing transactions
num_not_relayed unsigned int; number of non-relayed transactions
oldest unsigned int; unix time of the oldest transaction in the pool
txs_total unsigned int; total number of transactions.
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Example:
Send a command to the daemon to safely disconnect and shut down.
Alias: None.
Inputs: None.
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
Example:
Alias:
/getinfo
get_info
Get daemon bandwidth limits.
Alias: None.
Inputs: None.
Outputs:
limit_down - unsigned int; Download limit in kBytes per second
limit_up - unsigned int; Upload limit in kBytes per second
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Example:
Set daemon bandwidth limits.
Alias: None.
Inputs:
limit_down - signed int; Download limit in kBytes per second (-1 reset to default, 0 don't change the current limit)
limit_up - signed int; Upload limit in kBytes per second (-1 reset to default, 0 don't change the current limit)
Outputs:
limit_down - unsigned int; Download limit in kBytes per second
limit_up - unsigned int; Upload limit in kBytes per second
status - string; General RPC error code. "OK" means everything looks good.
Example:
Limit number of Outgoing peers.
Alias: None.
Inputs:
out_peers - unsigned int; Max number of outgoing peers
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
Example:
Limit number of Incoming peers.
Alias: None.
Inputs:
in_peers - unsigned int; Max number of incoming peers
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
Example:
Obsolete. Conserved here for reference.
Alias: None.
Inputs: None.
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
Example:
Obsolete. Conserved here for reference.
Alias: None.
Inputs: None.
Outputs:
status - string; General RPC error code. "OK" means everything looks good.
Example:
Get outputs.
Alias: None.
Inputs:
outputs array of get_outputs_out structure as follows:
amount - unsigned int;
index - unsigned int;
Outputs:
outs - array of structure outkey as follows:
height - unsigned int; block height of the output
key - String; the public key of the output
mask - String
txid - String; transaction id
unlocked - boolean; States if output is locked (false
) or not (true
)
status - string; General RPC error code. "OK" means everything looks good.
untrusted - boolean; States if the result is obtained using the bootstrap mode, and is therefore not trusted (true
), or when the daemon is fully synced (false
).
Update daemon.
Alias: None.
Inputs:
command - String; command to use, either check
or download
path - String; Optional, path where to download the update.
Outputs:
auto_uri - string;
hash - string;
path - String; path to download the update
status - string; General RPC error code. "OK" means everything looks good.
update - boolean; States if an update is available to download (true
) or not (false
)
user_uri - string;
version - string; Version available for download.
Example:
Session is an open-source encrypted messenger powered by Oxen, designed to provide both security and anonymity through metadata minimisation, fully anonymous signup, and secure encryption and networking protocols. Session uses the Oxen Service Node network to route and temporarily store messages.
The past decade has seen a massive increase in the number of people using — and relying on — instant messengers for everything from chatting with friends to mission-critical business tasks. The most widely-used messengers have amassed more than a billion users. However, these popular messengers have some serious privacy and security shortfalls that make them completely unsuitable for anyone concerned about their online privacy.
Some messengers, such as WhatsApp, have deployed end-to-end encryption in an attempt to alleviate user concerns about privacy and security. However, simply encrypting the contents of user messages doesn't fix the wider underlying issue: the companies that operate these services can still see massive amounts of metadata about their users' messaging activities. This metadata can include user IP addresses and phone numbers, the time and #️quantity of sent messages, and the relationship each account has with other accounts. Increasingly, it is the existence and analysis of this metadata that poses a significant privacy risk to journalists, human rights activists, and other groups with a real need for private communications.
Session is, in large part, a response to this growing risk. Session is built to minimise metadata creation and leakage at every step of the messaging process. Through its fully anonymous signup process, decentralised networking infrastructure, and encryption and onion routing protocols, Session ensures that users send messages — not metadata.
Resource Name | Description |
---|---|
Guide | Description |
---|---|
Once you have exported your view key (or not), the GUI wallet will display the “Wallet Created Page” which shows the address of your newly created hardware wallet. This address should match what is on your ledger device. At this point the wallet has been successfully created. Click “open wallet” and the GUI will navigate to the regular wallet dashboard page where you can spend/stake etc as usual.
If you have questions or need help with this guide feel free to reach out to us on or .
Once accepted by the network, the Service Node starts performing node operations and becomes eligible to receive periodic block in the form of $OXEN.
and can have the reward automatically distributed among them.
Receive, store, and forward encrypted messages
Route traffic
Are called into quorums that give them authority over transactions
Produce new blocks for the network via
Firstly, please consult the panel of the , where you will find a breakdown of the current Service Node network by country and network owner.
Network diversity: distribution across multiple and network providers to minimise the effects of fire, flooding, network splits, equipment failure, cable rupture, bankruptcy, industrial espionage and rogue employees
Software diversity: multiple operating systems, distributions and release variants to minimise the effects of events that target or otherwise afflict a particular system, such as a or the push of a buggy package.
If your server goes down while staked, your Service Node could be and your funds locked for 30 days (without receiving rewards).
Hosting Provider | Product Name | Cost Per Month ($USD) |
---|
Note: We do not endorse any of these providers. The above list is merely a selection of some of the popular options at the time of writing. Of course, this popularity comes at the expense of decentralisation. To provide even greater value to the network, please consider running a node in a country and/or on a network with few or even no nodes according to the . A useful resource in choosing a less common VPS provider is . Another good one is .
The better ones will utilise . In particular, you should steer clear of VPSes that use OpenVZ. This is an incomplete form of virtualisation that allows VPS capacity to be oversold, and is usually incompatible with the service node software. Virtual machines created with it often lack a /dev/tun
device, and even those that have this can still cause insurmountable problems for Lokinet.
If you are an individual staker and do not require any other contributors to run your Service Node, jump into the section.
If you want to run a pooled Service Node, jump into .
Well done! Continue to to make sure your Service Node is running properly.
You can also check your node's status by looking for your <Service Node Public Key>
in the "Service Nodes Awaiting Contributions" section on .
For a guide on staking to a shared Oxen Service Node as a contributor,
You can now jump onto , open the full list of active Service Nodes, and use Cmd+F
/Ctrl+F
to check if your Service Node's public key appears in the list.
You can also unlock your stake by running the following command from the :
can be issued at any point during the active lifecycle of a Service Node, including during the period after requesting an unlock. Deregistration removes your Service Node from the network, and your stake(s) become locked and unspendable for 30 days (21600 blocks) from the block in which the Service Node was deregistered.
Another helpful tool is Konstantin Ullrich's for Android.
For tips and tricks to maintain your Service Node, check out .
Having trouble? Just .
You will be prompted for a password. Enter a new password that follows the and press [Enter].
Block blob data - array of strings; list of block blobs which have been mined. See to get a blob on which to mine.
block_header - A structure containing block header information. See .
Similar to above, this method includes a block's height as an input parameter to retrieve basic information about the block.
block_header - A structure containing block header information. See .
Similar to above, but for a range of blocks. This method includes a starting block height and an ending block height as parameters to retrieve basic information about the range of blocks.
headers - array of block_header
(a structure containing block header information. See ).
block_header - A structure containing block header information. See .
See other RPC Methods
bootstrap_daemon_address - string; to give immediate usability to wallets while syncing by proxying RPC to it. (Note: the replies may be untrustworthy).
info - structure of connection info, as defined in
Note: It is recommended to use JSON RPC where such alternatives exist, rather than the following methods. For example, the recommended way to get a node's height is via the JSON RPC methods or , rather than below.
This method is a convenient backward support and should not be used anymore. See JSON RPC for details.
Reworked from RPC calls for Oxen under their .
You can download Session for Windows, macOS, Linux, iOS, or Android , where you can also find more information about the app, including details about its encryption protocol and more.
Looking to register a permanent name for your Account ID? Head over to .
How to host and maintain an Oxen Service Node using a Debian package and CLI wallet.
How to stake to a shared Oxen Service Node as a contributor.
Statistics, data, maps, and other information on Oxen Service Nodes.
List of Oxen Service Node JSON 2.0 RPC calls (advanced users only).
The Oxen Blockchain Explorer, with a list of current Service Node public keys.
How to prepare for setting up the Oxen GUI Wallet on Windows.
How to set up the Oxen GUI Wallet for the first time.
A brief walkthrough on how to use the GUI wallet.
How to export your Oxen wallet's transaction history as a CSV file.
How to restore your wallet from spend and view keys.
How to restore your wallet using its 25-word mnemonic seed phrase.
A list and explanation of the different commands available within oxen-wallet-cli
.
How to configure oxen-wallet-cli
for the first time on macOS.
How to setup the Oxen CLI Wallet on the Ledger Hardware Wallet.
How to export your Oxen wallet's transaction history as a CSV file.
How to use the Oxen Mobile wallet for the first time.
How to stake to an Oxen Service Node via the Oxen Mobile Wallet
State
Description
Awaiting
Service node is awaiting the staking requirement being met.
Active
Service node is staked, performing tasks as required, and receiving rewards.
Decommissioned
Service node is not performing tasks as required or is not meeting uptime standards, and has been put into an inactive state where it does not receive rewards.
Deregistered
Service node has been inactive for too long, and has been deregistered.
Variable
Value
INITIAL_CREDIT
60 blocks (~2 hours) of decommission time.
CREDIT_PER_DAY
24 blocks (~0.8 hours) of decommission time.
DECOMMISSION_MAX_CREDIT
1440 blocks (~48 hours) of decommission time.
MINIMUM
60 blocks(~2 hours) of decommission time.
Task
Description
Uptime Proofs
The quorum will check to see if a service node has provided uptime proofs within the last 2 hours. If a Service Node is found to have not provided uptime proofs, but it has at least MINIMUM
credits, it will be decommissioned. If it does not have at least MINIMUM
credits, it will be directly deregistered.
IP Changes
The quorum checks to see if the SN has advertised more than one IP to the network in the last 24 hours. If a service node's advertised IP has changed, it will be forced to the bottom of the service node reward list.
Checkpointing
The quorum checks that each service node within the quorum has provided a hash of a block for a specific block height (refer to Checkpointing for more information on this procedure). If a service node within the quorum does not provide a hash, but it has at least MINIMUM
credits, it will be decommissioned. If it does not have at least MINIMUM
credits, it will be directly deregistered.
State_Change_Transaction
Description
Register TX
A transaction (lock transfer) created from the client registering the service node.
State Change: Awaiting -> Active
Note: This is not a quorum transaction.
Decommission TX
The service node is temporarily deregistered; it remains in the service node list, but is removed from the rewards list and from any network duties.
State Change: Active -> Decommissioned
Recommission TX
The service node is added back to the service node list and placed at the bottom of the rewards list.
Stage Change: Decommissioned -> Active
IP Change TX
The service node is put at the bottom of the rewards list as punishment for changing its IP. Stage Change: N/A (no change)
Deregister TX
The service node is deregistered.
State Change: Active -> Deregistered
/ Decommissioned -> Deregistered
Netcup | VPS 1000 G8 | 10.50 |
Evolution Host | STARTER | 5.50 |
Online.net | Start-2-S-SSD | 13.99 |
Scaleway | START1-M | 9.33 |
OVH | VPS SSD 2 | 7.61 |
Leaseweb | Virtual Server XL | 34.45 |
Digital Ocean | 4 GB, 2 vCPUs | 20 (24 from 22-07-0 |
Linode | 4 GB, 2 vCPUs | 20 |
Feral Hosting | Neon Capability | 19.68 |
Trabia | VDS-8G | 38.54 |
Hetzner | EX41-SSD (30 TB) | 39.71 |
How to install Session on Debian based Linux distributions
At its core, Session is built on the Oxen Service Node network, so it's important to understand how the Oxen network functions to support Session's mission of enabling decentralised anonymous communications.
Many projects have attempted to establish decentralised permission-less networks. These projects have often found themselves struggling with a ‘tragedy of the commons’ of sorts, wherein public servers, required for the operation of the network, are under-resourced and overused. This inadvertently causes the network to provide poor service to users, which discourages further use or expansion of the network.
Conversely, those projects which are able to create large, public permissionless networks find themselves constantly facing questions about the parties that contribute to running that infrastructure. This can be especially damaging when the operation of that infrastructure can adversely affect the privacy, security, or user experience of an application. For example, the Tor network faces constant questions about evidence of Sybil attacks from unknown parties attempting to run large sections of of the public routing network, which could be used to de-anonymise users .
Session seeks to avoid these issues through using a different type of public access network: a staked routing and storage network called the Oxen Service Node network. This network is based on the Oxen blockchain, which itself is based on the CryptoNote protocol. Through the integration of a blockchain network, Session creates a financial precondition for anyone wishing to host a server on the network (and thus participate in Session’s message storage and routing architecture).
Authorisation for a server to operate on the network is attained through the server operator conducting a special staking transaction, which requires that an operator provably lock an amount of Oxen cryptocurrency assigned to their node (previously, this staking requirement was algorithmically adjusted over time; it is now fixed at 15,000 $OXEN).
This staking system provides a defense against Sybil attacks by limiting attackers based on the amount of financial resources they have available. The staking system also achieves two other goals which further reduce the likelihood of a Sybil attack.
Firstly, the need for attackers to buy or control $OXEN to run service nodes creates a feedback loop of increasing price for anyone attempting to run large portions of the network. That is, as the attacker buys or acquires more $OXEN and locks it, removing it from the circulating supply, the supply of Oxen is decreased and the demand from the attacker must be sustained. This causes the price of any remaining Oxen to increase, furthering the feedback loop of increasing prices. Secondly, the staking system binds an attacker to their stake, meaning if they are found to be performing active attacks, the underlying value of their stake can sharply decline as users lose trust in the network, or could be destroyed or locked by the network, in any case increasing the attackers sunken costs.
The other main advantage of a staked blockchain network is that service nodes earn rewards for the work they do. Service nodes are rewarded with a portion of the block reward minted upon the creation of each new block. This system makes Session distinct from altruistic networks like Tor and I2P by providing an incentive linked directly with the performance of a service node. Honest node behaviour and the provision of a minimum standard of operation is ensured through a consensus-based testing suite. Misbehaving nodes face the threat of having their staked capital locked, while the previously-mentioned cryptocurrency rewards function as the positive incentive for nodes to behave honestly and provide at least a minimum standard of service to the network.
The other foundational component of Session is an onion routing protocol, referred to as onion requests, which enables Session clients to obfuscate their IP addresses by creating a 3-hop randomised path through the Oxen Service Node network. Onion requests use a straightforward onion routing protocol which successively encrypts each request for each of the three hops, ensuring the first service node only knows the IP address of the client and the IP address of the middle service node, the middle service node only knows the IP address of the first and last service nodes, and the last service node only knows the IP address of the middle service node and the final destination IP address for the request.
Each Session client establishes a path on start-up, and once established, all requests for messages, attachments and meta information are sent through this path. Session clients establish a path by selecting three random nodes from their service node list (see bootstrapping), which contains each service node’s IP address, storage server port, and X25519 key. Clients use this information to create an onion, with each layer being encrypted with the X25519 key of its respective service node. This onion is sent to the first service node’s storage server; this service node then decrypts its layer of the onion. When a service node unwraps a layer, the destination key for the next node is revealed. The first service node decrypts its layer and initialises a ZMQ connection with the specified downstream node. When the onion reaches the final node in the path, that node sends a path build success message backwards through the path, which indicates a successful path built upon its receipt by the client.
Upon receiving the path build success message, the client will encrypt their messages with the X25519 keys of the final destination, be that a service node, file server, open group server, or client. The client also includes an ephemeral X25519 key in their request. When the destination server or client receives the request, they decrypt it and generate a response. This response is then sent back down the previously-established path, encrypted for the initial sender’s (the client’s) ephemeral key, so that the client can decrypt the response upon receiving it.
Onion requests provide a straightforward anonymous networking layer, and the Oxen Service Node network provides an incentivised, self-regulating network of remote servers which provide bandwidth and storage space. A number of services have been built on this foundation in order to give Session features commonly expected of modern messaging applications.
Message storage is an essential feature for any chat application aiming to provide a good user experience. When a user sends a message, they expect the recipient to receive that message even if the recipient's device goes offline or is turned off after the message has been sent. Users also expect the user on the other end to receive the message when their device wakes up or reconnects from an offline state. Apps that run on decentralised networks typically cannot provide this experience, because of the lack of incentive structures and, consequently, the ephemeral nature of clients and servers on such a network. Session is able to provide message storage through the incentivised service node network and its usage of swarms.
Although the Oxen blockchain incentivises correct service node behaviour through rewards and punishments, these incentive models cannot prevent nodes going offline unexpectedly due to operator choice, software bugs, or data centre outages. Therefore, for redundancy, a secondary logical data storage layer must be built on top of the service node network to ensure reliable message storage and retrieval.
This secondary logical layer is created by replicating stored messages across small groupings of service nodes called swarms. The swarm a service node initially joins is determined at the time of that service node’s registration, with the service node having minimal influence over which swarm it joins. This protects against swarms being entirely made up of malicious or non-performant nodes, which is important to maintain the network’s self-regulating properties.
Composition of each swarm inevitably changes as the networks evolves: some nodes leave the network and the newly registered nodes take their place. If a swarm loses a large number of nodes it may additionally "steal" a node from some other, larger swarm. In the unlikely event that the network has no swarms to steal from (i.e., every swarm is at Nmin=5 nodes), the ‘starving’ swarm (a swarm with fewer than Nmin nodes) will be dissolved and its nodes will be redistributed among the remaining swarms. Conversely, when a large number of nodes enter the network that would oversaturate existing swarms (i.e., every swarm is already at max capacity Nmax=10), a new swarm is created from a random selection of Ntarget=7 excess nodes. Note that Nmin < Ntarget < Nmax to ensure that a newly generated swarm doesn’t get dissolved shortly after and that there is still room for growth.
The outcome of this algorithm is the creation and, when necessary, rebalancing of swarms of around Nmin–Nmax service nodes which store and serve Session clients’ messages. The goal of the swarm algorithm is to ensure that no swarm is controlled by a single entity and that the network is resilient enough to handle both small and large scale events where service nodes are no longer contactable, ensuring data integrity and privacy in both cases.
The following set of simple rules ensure that service nodes within swarms remain synchronised as the composition of swarms changes:
When a node joins a new swarm, existing swarm members recognise this and push the swarm’s data records to the new member. When a node leaves a swarm, its existing records can be safely erased, with the exception of when the node is migrating from a dissolving swarm. In this case, the migrating node determines the swarms responsible for its records and distributes them accordingly.
The majority of popular messaging applications require the user to register with an email or phone number in order to use the service. This provides some advantages, including account verification, for purposes of spam protection, and social network discoverability. However, such requirements also create some major privacy and security issues for users.
The use of a phone number as the basis for ownership of an identity key/long-term key pair weakens security against user accounts being compromised, such as in the cases of popular applications like Signal and WhatsApp. This weakness primarily stems from the fact that phone numbers are managed by centralised service providers (i.e. telecommunications service providers) who can circumvent user control, allowing these providers to assume direct control of specific users’ numbers. Widespread legislation already exists to compel service providers to take this kind of action. Additionally, methods such as SIM swapping attacks, service provider hacking, and phone number recycling can all be exploited by lower-level actors .
Signal and Whatsapp put forward varying degrees of protection against these types of attacks. Signal and WhatsApp both send a 'Safety numbers have changed' warning to a user's contacts if identity keys are changed. In practice, however, users rarely verify these details out-of-band .
Both Signal and WhatsApp also allow users to set a "registration PIN lock" . This protection means that an attacker (including a service provider or state-level actor) needs access to both the phone number and the registration PIN code to modify identity keys. However, this feature is off by default, difficult to find in the settings menu, and automatically disabled after periods of user inactivity. These factors all significantly reduce the efficacy of registration PIN locks as a protective measure against the security risks of phone number-linked accounts.
Using phone numbers as the basis for account registration also greatly weakens the privacy achievable by an average user. In most countries, users must provide personally identifiable information such as a passport, drivers' license or identity card to obtain a phone number — permanently mapping users’ identities to their phone numbers. These identity mappings are kept in private databases that can be queried by governments or the service providers that own them. There are also a number of web scrapers and indexers that automatically scrape phone numbers associated with individuals. These scrapers may target sources such as leaked databases, public social media profiles, and business phone numbers to link people to their phone numbers. Since the only method of initiating contact with a user in Signal, WhatsApp, or similar application is to know the user’s phone number, this immediately strips away user anonymity — a significant concern for whistleblowers, activists, protestors and other such users.
Account systems based on phone numbers also limit the potential for the establishment of multiple identities by a single user. These systems also prevent high-risk users without access to a phone number from accessing these services.
Session does not use email addresses or phone numbers as the basis of its account system. Instead, user identity is established through the generation of X25519 public-private key pairs. These key pairs are not required to be linked with any other identifier, and new key pairs can be generated on-device in seconds. This means that each key pair (and thus, each account) is pseudonymous, unless intentionally linked with an individual identity by the user through out-of-band activity.
Because Session does not have a central server to keep records of user identities, the commonly expected user experience of being able to recover or log back into an account using a username and password is not possible. Instead, users are prompted to write down their long-term private key (represented as a mnemonic seed, referred to within Session as a recovery phrase) upon account generation. A user can use this backup key to recover their account if their device is lost or destroyed, and the user's contacts will be able to continue contacting that same user account, rather than having to re-initiate contact with a new key.
Some SOGS operators may want to setup a room on their SOGS which features one way style communication, these rooms allow moderators and administrators to update the room with new messages, but disallows unprivileged users to send new messages. These sorts of rooms can be useful for providing updates or information.
*Skip to step 3 if you already have a room and you are an administrator in that room*
Replace TOKEN
with the address to use in the room URL (which must consist of ONLY lowercase letters, numbers, underscores, or dashes), replace NAME
with the room name to display in Session and optionally replace DESCRIPTION
with a short description of the topic of the room.
replacing TOKEN with the room token you created in step 1 and replacing ACCOUNTID with your own Account ID
There are 4 types of permission currently available in rooms
r = Read (ability to read messages)
w = Write (ability to write new messages)
u = Upload (ability to upload attachments, including files, voice notes, images and videos)
a = Access (ability to join the room)
When modifying these permissions changes will only apply to non admins/moderators, the default permissions in a room will be "rwua" for all users
To create a read only group we want to remove regular users ability to write and upload attachments, we can do this using the following command
This command will ensure read and access permissions are provided and remove write and upload permissions for regular users.
As the permission changes do not affect administrators and moderators, they will still be able to read, write and upload to the group. New Account ID's can be given write/upload access by making those Account ID's moderator or admin, this can be done directly in the Session Desktop client or via the CLI.
This is a list of the oxen-wallet-rpc calls, their inputs and outputs, and examples of each. The program oxen-wallet-rpc replaced the rpc interface that was in simplewallet and then oxen-wallet-cli.
All oxen-wallet-rpc methods use the same JSON RPC interface. For example:
If the oxen-wallet-rpc was executed with the --rpc-login
argument as username:password
, then follow this example:
Note: "atomic units" refer to the smallest fraction of 1 $OXEN according to the oxend implementation. 1 $OXEN = 1e9 atomic units.
get_balance
get_address
get_address_index
create_address
label_address
get_accounts
create_account
label_account
get_account_tags
tag_accounts
untag_accounts
set_account_tag_description
get_height
transfer
transfer_split
sign_transfer
submit_transfer
sweep_dust
sweep_all
sweep_single
relay_tx
store
get_payments
get_bulk_payments
incoming_transfers
query_key
make_integrated_address
split_integrated_address
stop_wallet
rescan_blockchain
set_tx_notes
get_tx_notes
set_attribute
get_attribute
get_tx_key
check_tx_key
get_tx_proof
check_tx_proof
get_spend_proof
check_spend_proof
get_reserve_proof
check_reserve_proof
get_transfers
get_transfer_by_txid
sign
verify
export_outputs
import_outputs
export_key_images
import_key_images
make_uri
parse_uri
get_address_book
add_address_book
delete_address_book
refresh
rescan_spent
start_mining
stop_mining
get_languages
create_wallet
open_wallet
close_wallet
change_wallet_password
is_multisig
prepare_multisig
make_multisig
export_multisig_info
import_multisig_info
finalize_multisig
sign_multisig
submit_multisig
get_version
Return the wallet's balance.
Alias: getbalance.
Inputs:
account_index - unsigned int; Return balance for this account.
address_indices - array of unsigned int; (Optional) Return balance detail for those subaddresses.
Outputs:
balance - unsigned int; The total balance of the current Oxen-wallet-rpc in session.
unlocked_balance - unsigned int; Unlocked funds are those funds that are sufficiently deep enough in the Oxen blockchain to be considered safe to spend.
multisig_import_needed - boolean; True if importing multisig data is needed for returning a correct balance.
per_subaddress - array of subaddress information; Balance information for each subaddress in an account.
address_index - unsigned int; Index of the subaddress in the account.
address - string; Address at this index. Base58 representation of the public keys.
balance - unsigned int; Balance for the subaddress (locked or unlocked).
unlocked_balance - unsigned int; Unlocked balance for the subaddress.
label - string; Label for the subaddress.
num_unspent_outputs - unsigned int; Number of unspent outputs available for the subaddress.
Example:
Return the wallet's addresses for an account. Optionally filter for specific set of subaddresses.
Alias: getaddress.
Inputs:
account_index - unsigned int; Return subaddresses for this account.
address_index - array of unsigned int; (Optional) List of subaddresses to return from an account.
Outputs:
address - string; The 95-character hex address string of the oxen-wallet-rpc in session.
addresses array of addresses informations
address string; The 95-character hex (sub)address string.
label string; Label of the (sub)address
address_index unsigned int; index of the subaddress
used boolean; states if the (sub)address has already received funds
Example:
Get account and address indexes from a specific (sub)address
Alias: None.
Inputs:
address - String; (sub)address to look for.
Outputs:
index - subaddress informations
major unsigned int; Account index.
minor unsigned int; Address index.
Example:
Create a new address for an account. Optionally, label the new address.
Alias: None.
Inputs:
account_index - unsigned int; Create a new address for this account.
label - string; (Optional) Label for the new address.
Outputs:
address - string; Newly created address. Base58 representation of the public keys.
address_index - unsigned int; Index of the new address under the input account.
Example:
Label an address.
Alias: None.
Inputs:
index - subaddress index; JSON Object containing the major & minor address index:
major - unsigned int; Account index for the subaddress.
minor - unsigned int; Index of the subaddress in the account.
label - string; Label for the address.
Outputs: None.
Example:
Get all accounts for a wallet. Optionally filter accounts by tag.
Alias: None.
Inputs:
tag - string; (Optional) Tag for filtering accounts.
Outputs:
subaddress_accounts - array of subaddress account information:
account_index - unsigned int; Index of the account.
balance - unsigned int; Balance of the account (locked or unlocked).
base_address - string; Base64 representation of the first subaddress in the account.
label - string; (Optional) Label of the account.
tag - string; (Optional) Tag for filtering accounts.
unlocked_balance - unsigned int; Unlocked balance for the account.
total_balance - unsigned int; Total balance of the selected accounts (locked or unlocked).
total_unlocked_balance - unsigned int; Total unlocked balance of the selected accounts.
Example:
Create a new account with an optional label.
Alias: None.
Inputs:
label - string; (Optional) Label for the account.
Outputs:
account_index - unsigned int; Index of the new account.
address - string; Address for this account. Base58 representation of the public keys.
Example:
Label an account.
Alias: None.
Inputs:
account_index - unsigned int; Apply label to account at this index.
label - string; Label for the account.
Outputs: None.
Example:
Get a list of user-defined account tags.
Alias: None.
Inputs: None.
Outputs:
account_tags - array of account tag information:
tag - string; Filter tag.
label - string; Label for the tag.
accounts - array of int; List of tagged account indices.
Example:
Apply a filtering tag to a list of accounts.
Alias: None.
Inputs:
tag - string; Tag for the accounts.
accounts - array of unsigned int; Tag this list of accounts.
Outputs: None.
Example:
Remove filtering tag from a list of accounts.
Alias: None.
Inputs:
accounts - array of unsigned int; Remove tag from this list of accounts.
Outputs: None.
Example:
Set description for an account tag.
Alias: None.
Inputs:
tag - string; Set a description for this tag.
description - string; Description for the tag.
Outputs: None.
Example:
Returns the wallet's current block height.
Alias: getheight.
Inputs: None.
Outputs:
height - unsigned int; The current oxen-wallet-rpc's blockchain height. If the wallet has been offline for a long time, it may need to catch up with the daemon.
Example:
Send $OXEN to a number of recipients.
Alias: None.
Inputs:
destinations - array of destinations to receive $OXEN:
amount - unsigned int; Amount to send to each destination, in atomic units.
address - string; Destination public address.
account_index - unsigned int; (Optional) Transfer from this account index. (Defaults to 0)
subaddr_indices - array of unsigned int; (Optional) Transfer from this set of subaddresses. (Defaults to 0)
priority - unsigned int; Set a priority for the transaction. Accepted Values are: 0-3 for: default, unimportant, normal, elevated, priority.
mixin - unsigned int; Number of outputs from the blockchain to mix with (0 means no mixing).
ring_size - unsigned int; Number of outputs to mix in the transaction (this output + N decoys from the blockchain).
unlock_time - unsigned int; Number of blocks before the $OXEN can be spent (0 to not add a lock).
payment_id - string; (Optional) Random 32-byte/64-character hex string to identify a transaction.
get_tx_key - boolean; (Optional) Return the transaction key after sending.
do_not_relay - boolean; (Optional) If true, the newly created transaction will not be relayed to the Oxen network. (Defaults to false)
get_tx_hex - boolean; Return the transaction as hex string after sending (Defaults to false)
get_tx_metadata - boolean; Return the metadata needed to relay the transaction. (Defaults to false)
Outputs:
amount - Amount transferred for the transaction.
fee - Integer value of the fee charged for the txn.
multisig_txset - Set of multisig transactions in the process of being signed (empty for non-multisig).
tx_blob - Raw transaction represented as hex string, if get_tx_hex is true.
tx_hash - String for the publically searchable transaction hash.
tx_key - String for the transaction key if get_tx_key is true, otherwise, blank string.
tx_metadata - Set of transaction metadata needed to relay this transfer later, if get_tx_metadata is true.
unsigned_txset - String. Set of unsigned tx for cold-signing purposes.
Example:
Same as transfer, but can split into more than one tx if necessary.
Alias: None.
Inputs:
destinations - array of destinations to receive $OXEN:
amount - unsigned int; Amount to send to each destination, in atomic units.
address - string; Destination public address.
account_index - unsigned int; (Optional) Transfer from this account index. (Defaults to 0)
subaddr_indices - array of unsigned int; (Optional) Transfer from this set of subaddresses. (Defaults to 0)
mixin - unsigned int; Number of outputs from the blockchain to mix with (0 means no mixing).
ring_size - unsigned int; Sets ringsize to n (mixin + 1).
unlock_time - unsigned int; Number of blocks before the $OXEN can be spent (0 to not add a lock).
payment_id - string; (Optional) Random 32-byte/64-character hex string to identify a transaction.
get_tx_keys - boolean; (Optional) Return the transaction keys after sending.
priority - unsigned int; Set a priority for the transactions. Accepted Values are: 0-3 for: default, unimportant, normal, elevated, priority.
do_not_relay - boolean; (Optional) If true, the newly created transaction will not be relayed to the Oxen network. (Defaults to false)
get_tx_hex - boolean; Return the transactions as hex string after sending
new_algorithm - boolean; True to use the new transaction construction algorithm, defaults to false.
get_tx_metadata - boolean; Return list of transaction metadata needed to relay the transfer later.
Outputs:
tx_hash_list - array of: string. The tx hashes of every transaction.
tx_key_list - array of: string. The transaction keys for every transaction.
amount_list - array of: integer. The amount transferred for every transaction.
fee_list - array of: integer. The amount of fees paid for every transaction.
tx_blob_list - array of: string. The tx as hex string for every transaction.
tx_metadata_list - array of: string. List of transaction metadata needed to relay the transactions later.
multisig_txset - string. The set of signing keys used in a multisig transaction (empty for non-multisig).
unsigned_txset - string. Set of unsigned tx for cold-signing purposes.
Example:
Sign a transaction created on a read-only wallet (in cold-signing process)
Alias: None.
Inputs:
unsigned_txset - string. Set of unsigned tx returned by "transfer" or "transfer_split" methods.
export_raw - boolean; (Optional) If true, return the raw transaction data. (Defaults to false)
Outputs:
signed_txset - string. Set of signed tx to be used for submitting transfer.
tx_hash_list - array of: string. The tx hashes of every transaction.
tx_raw_list - array of: string. The tx raw data of every transaction.
In the example below, we first generate an unsigned_txset on a read only wallet before signing it:
Generate unsigned_txset using the above "transfer" method on read-only wallet:
Sign tx using the previously generated unsigned_txset
Submit a previously signed transaction on a read-only wallet (in cold-signing process).
Alias: None.
Inputs:
tx_data_hex - string; Set of signed tx returned by "sign_transfer"
Outputs:
tx_hash_list - array of: string. The tx hashes of every transaction.
In the example below, we submit the transfer using the signed_txset generated above:
Send all dust outputs back to the wallet's, to make them easier to spend (and mix).
Alias: sweep_unmixable.
Inputs:
get_tx_keys - boolean; (Optional) Return the transaction keys after sending.
do_not_relay - boolean; (Optional) If true, the newly created transaction will not be relayed to the Oxen network. (Defaults to false)
get_tx_hex - boolean; (Optional) Return the transactions as hex string after sending. (Defaults to false)
get_tx_metadata - boolean; (Optional) Return list of transaction metadata needed to relay the transfer later. (Defaults to false)
Outputs:
tx_hash_list - array of: string. The tx hashes of every transaction.
tx_key_list - array of: string. The transaction keys for every transaction.
amount_list - array of: integer. The amount transferred for every transaction.
fee_list - array of: integer. The amount of fees paid for every transaction.
tx_blob_list - array of: string. The tx as hex string for every transaction.
tx_metadata_list - array of: string. List of transaction metadata needed to relay the transactions later.
multisig_txset - string. The set of signing keys used in a multisig transaction (empty for non-multisig).
unsigned_txset - string. Set of unsigned tx for cold-signing purposes.
Example (In this example, sweep_dust
returns nothing because there are no funds to sweep):
Send all unlocked balance to an address.
Alias: None.
Inputs:
address - string; Destination public address.
account_index - unsigned int; Sweep transactions from this account.
subaddr_indices - array of unsigned int; (Optional) Sweep from this set of subaddresses in the account.
priority - unsigned int; (Optional) Priority for sending the sweep transfer, partially determines fee.
mixin - unsigned int; Number of outputs from the blockchain to mix with (0 means no mixing).
ring_size - unsigned int; Sets ringsize to n (mixin + 1).
unlock_time - unsigned int; Number of blocks before the $OXEN can be spent (0 to not add a lock).
payment_id - string; (Optional) Random 32-byte/64-character hex string to identify a transaction.
get_tx_keys - boolean; (Optional) Return the transaction keys after sending.
below_amount - unsigned int; (Optional) Include outputs below this amount.
do_not_relay - boolean; (Optional) If true, do not relay this sweep transfer. (Defaults to false)
get_tx_hex - boolean; (Optional) return the transactions as hex encoded string. (Defaults to false)
get_tx_metadata - boolean; (Optional) return the transaction metadata as a string. (Defaults to false)
Outputs:
tx_hash_list - array of: string. The tx hashes of every transaction.
tx_key_list - array of: string. The transaction keys for every transaction.
amount_list - array of: integer. The amount transferred for every transaction.
fee_list - array of: integer. The amount of fees paid for every transaction.
tx_blob_list - array of: string. The tx as hex string for every transaction.
tx_metadata_list - array of: string. List of transaction metadata needed to relay the transactions later.
multisig_txset - string. The set of signing keys used in a multisig transaction (empty for non-multisig).
unsigned_txset - string. Set of unsigned tx for cold-signing purposes.
Example:
Send all of a specific unlocked output to an address.
Alias: None.
Inputs:
address - string; Destination public address.
account_index - unsigned int; Sweep transactions from this account.
subaddr_indices - array of unsigned int; (Optional) Sweep from this set of subaddresses in the account.
priority - unsigned int; (Optional) Priority for sending the sweep transfer, partially determines fee.
mixin - unsigned int; Number of outputs from the blockchain to mix with (0 means no mixing).
ring_size - unsigned int; Sets ringsize to n (mixin + 1).
unlock_time - unsigned int; Number of blocks before the $OXEN can be spent (0 to not add a lock).
payment_id - string; (Optional) Random 32-byte/64-character hex string to identify a transaction.
get_tx_keys - boolean; (Optional) Return the transaction keys after sending.
key_image - string; Key image of specific output to sweep.
below_amount - unsigned int; (Optional) Include outputs below this amount.
do_not_relay - boolean; (Optional) If true, do not relay this sweep transfer. (Defaults to false)
get_tx_hex - boolean; (Optional) return the transactions as hex encoded string. (Defaults to false)
get_tx_metadata - boolean; (Optional) return the transaction metadata as a string. (Defaults to false)
Outputs:
tx_hash_list - array of: string. The tx hashes of every transaction.
tx_key_list - array of: string. The transaction keys for every transaction.
amount_list - array of: integer. The amount transferred for every transaction.
fee_list - array of: integer. The amount of fees paid for every transaction.
tx_blob_list - array of: string. The tx as hex string for every transaction.
tx_metadata_list - array of: string. List of transaction metadata needed to relay the transactions later.
multisig_txset - string. The set of signing keys used in a multisig transaction (empty for non-multisig).
unsigned_txset - string. Set of unsigned tx for cold-signing purposes.
Example:
Relay a transaction previously created with "do_not_relay":true
.
Alias: None.
Inputs:
hex - string; transaction metadata returned from a transfer
method with get_tx_metadata
set to true
.
Outputs:
tx_hash - String for the publically searchable transaction hash.
Example:
Save the wallet file.
Alias: None.
Inputs: None.
Outputs: None.
Example:
Get a list of incoming payments using a given payment id.
Alias: None.
Inputs:
payment_id - string; Payment ID used to find the payments (16 characters hex).
Outputs:
payments - list of:
payment_id - string; Payment ID matching the input parameter.
tx_hash - string; Transaction hash used as the transaction ID.
amount - unsigned int; Amount for this payment.
block_height - unsigned int; Height of the block that first confirmed this payment.
unlock_time - unsigned int; Time (in block height) until this payment is safe to spend.
subaddr_index - subaddress index:
major - unsigned int; Account index for the subaddress.
minor - unsigned int; Index of the subaddress in the account.
address - string; Address receiving the payment; Base58 representation of the public keys.
Example:
Get a list of incoming payments using a given payment id, or a list of payments ids, from a given height. This method is the preferred method over get_payments
because it has the same functionality but is more extendable. Either is fine for looking up transactions by a single payment ID.
Alias: None.
Inputs:
payment_ids - array of: string; Payment IDs used to find the payments (16 characters hex).
min_block_height - unsigned int; The block height at which to start looking for payments.
Outputs:
payments - list of:
payment_id - string; Payment ID matching one of the input IDs.
tx_hash - string; Transaction hash used as the transaction ID.
amount - unsigned int; Amount for this payment.
block_height - unsigned int; Height of the block that first confirmed this payment.
unlock_time - unsigned int; Time (in block height) until this payment is safe to spend.
subaddr_index - subaddress index:
major - unsigned int; Account index for the subaddress.
minor - unsigned int; Index of the subaddress in the account.
address - string; Address receiving the payment; Base58 representation of the public keys.
Example:
Return a list of incoming transfers to the wallet.
Inputs:
transfer_type - string; "all": all the transfers, "available": only transfers which are not yet spent, OR "unavailable": only transfers which are already spent.
account_index - unsigned int; (Optional) Return transfers for this account. (defaults to 0)
subaddr_indices - array of unsigned int; (Optional) Return transfers sent to these subaddresses.
verbose - boolean; (Optional) Enable verbose output, return key image if true.
Outputs:
transfers - list of:
amount - unsigned int; Amount of this transfer.
global_index - unsigned int; Mostly internal use, can be ignored by most users.
key_image - string; Key image for the incoming transfer's unspent output (empty unless verbose is true).
spent - boolean; Indicates if this transfer has been spent.
subaddr_index - unsigned int; Subaddress index for incoming transfer.
tx_hash - string; Several incoming transfers may share the same hash if they were in the same transaction.
tx_size - unsigned int; Size of transaction in bytes.
Example, get all transfers:
Example, get available transfers:
Example, get unavailable transfers:
Return the spend or view private key.
Alias: None.
Inputs:
key_type - string; Which key to retrieve: "mnemonic" - the mnemonic seed (older wallets do not have one) OR "view_key" - the view key
Outputs:
key - string; The view key will be hex encoded, while the mnemonic will be a string of words.
Example (Query view key):
Example (Query mnemonic key):
Make an integrated address from the wallet address and a payment id.
Alias: None.
Inputs:
standard_address - string; (Optional, defaults to primary address) Destination public address.
payment_id - string; (Optional, defaults to a random ID) 16 characters hex encoded.
Outputs:
integrated_address - string
payment_id - string; hex encoded;
Example (Payment ID is empty, use a random ID):
Retrieve the standard address and payment id corresponding to an integrated address.
Alias: None.
Inputs:
integrated_address - string
Outputs:
is_subaddress - boolean; States if the address is a subaddress
payment - string; hex encoded
standard_address - string
Example:
Stops the wallet, storing the current state.
Alias: None.
Inputs: None.
Outputs: None.
Example:
Rescan the blockchain from scratch, losing any information which can not be recovered from the blockchain itself. This includes destination addresses, tx secret keys, tx notes, etc.
Alias: None.
Inputs: None.
Outputs: None.
Example:
Set arbitrary string notes for transactions.
Alias: None.
Inputs:
txids - array of string; transaction ids
notes - array of string; notes for the transactions
Outputs: None.
Example:
Get string notes for transactions.
Alias: None.
Inputs:
txids - array of string; transaction ids
Outputs:
notes - array of string; notes for the transactions
Example:
Set arbitrary attribute.
Alias: None.
Inputs:
key - string; attribute name
value - string; attribute value
Outputs: None.
Example:
Get attribute value by name.
Alias: None.
Inputs:
key - string; attribute name
Outputs:
value - string; attribute value
Example:
Get transaction secret key from transaction id.
Alias: None.
Inputs:
txid - string; transaction id.
Outputs:
tx_key - string; transaction secret key.
Example:
Check a transaction in the blockchain with its secret key.
Alias: None.
Inputs:
txid - string; transaction id.
tx_key - string; transaction secret key.
address - string; destination public address of the transaction.
Outputs:
confirmations - unsigned int; Number of block mined after the one with the transaction.
in_pool - boolean; States if the transaction is still in pool or has been added to a block.
received - unsigned int; Amount of the transaction.
Example:
Get transaction signature to prove it.
Alias: None.
Inputs:
txid - string; transaction id.
address - string; destination public address of the transaction.
message - string; (Optional) add a message to the signature to further authenticate the prooving process.
Outputs:
signature - string; transaction signature.
Example:
Prove a transaction by checking its signature.
Alias: None.
Inputs:
txid - string; transaction id.
address - string; destination public address of the transaction.
message - string; (Optional) Should be the same message used in get_tx_proof
.
signature - string; transaction signature to confirm.
Outputs:
confirmations - unsigned int; Number of block mined after the one with the transaction.
good - boolean; States if the inputs proves the transaction.
in_pool - boolean; States if the transaction is still in pool or has been added to a block.
received - unsigned int; Amount of the transaction.
In the example below, the transaction has been proven:
In the example below, the wrong message is used, avoiding the transaction to be proved:
Generate a signature to prove a spend. Unlike proving a transaction, it does not requires the destination public address.
Alias: None.
Inputs:
txid - string; transaction id.
message - string; (Optional) add a message to the signature to further authenticate the prooving process.
Outputs:
signature - string; spend signature.
Example:
Prove a spend using a signature. Unlike proving a transaction, it does not requires the destination public address.
Alias: None.
Inputs:
txid - string; transaction id.
message - string; (Optional) Should be the same message used in get_spend_proof
.
signature - string; spend signature to confirm.
Outputs:
good - boolean; States if the inputs proves the spend.
In the example below, the spend has been proven:
In the example below, the wrong message is used, avoiding the spend to be proved:
Generate a signature to prove of an available amount in a wallet.
Alias: None.
Inputs:
all - boolean; Proves all wallet balance to be disposable.
account_index - unsigned int; Specify the account from witch to prove reserve. (ignored if all
is set to true)
amount - unsigned int; Amount (in atomic units) to prove the account has for reserve. (ignored if all
is set to true)
message - string; (Optional) add a message to the signature to further authenticate the prooving process.
Outputs:
signature - string; reserve signature.
Example:
Proves a wallet has a disposable reserve using a signature.
Alias: None.
Inputs:
address - string; Public address of the wallet.
message - string; (Optional) Should be the same message used in get_reserve_proof
.
signature - string; reserve signature to confirm.
Outputs:
good - boolean; States if the inputs proves the reserve.
In the example below, the reserve has been proven:
In the example below, all wallet reserve has been proven:
In the example below, the wrong message is used, avoiding the reserve to be proved:
Returns a list of transfers.
Alias: None.
Inputs:
in - boolean; (Optional) Include incoming transfers.
out - boolean; (Optional) Include outgoing transfers.
pending - boolean; (Optional) Include pending transfers.
failed - boolean; (Optional) Include failed transfers.
pool - boolean; (Optional) Include transfers from the daemon's transaction pool.
filter_by_height - boolean; (Optional) Filter transfers by block height.
min_height - unsigned int; (Optional) Minimum block height to scan for transfers, if filtering by height is enabled.
max_height - unsigned int; (Opional) Maximum block height to scan for transfers, if filtering by height is enabled (defaults to max block height).
account_index - unsigned int; (Optional) Index of the account to query for transfers. (defaults to 0)
subaddr_indices - array of unsigned int; (Optional) List of subaddress indices to query for transfers. (defaults to 0)
Outputs:
in array of transfers:
address - string; Public address of the transfer.
amount - unsigned int; Amount transferred.
confirmations - unsigned int; Number of block mined since the block containing this transaction (or block height at which the transaction should be added to a block if not yet confirmed).
double_spend_seen - boolean; True if the key image(s) for the transfer have been seen before.
fee - unsigned int; Transaction fee for this transfer.
height - unsigned int; Height of the first block that confirmed this transfer (0 if not mined yet).
note - string; Note about this transfer.
payment_id - string; Payment ID for this transfer.
subaddr_index - JSON object containing the major & minor subaddress index:
major - unsigned int; Account index for the subaddress.
minor - unsigned int; Index of the subaddress under the account.
suggested_confirmations_threshold - unsigned int; Estimation of the confirmations needed for the transaction to be included in a block.
timestamp - unsigned int; POSIX timestamp for when this transfer was first confirmed in a block (or timestamp submission if not mined yet).
txid - string; Transaction ID for this transfer.
type - string; Transfer type: "in"
unlock_time - unsigned int; Number of blocks until transfer is safely spendable.
out array of transfers (see above).
pending array of transfers (see above).
failed array of transfers (see above).
pool array of transfers (see above).
Example:
Show information about a transfer to/from this address.
Alias: None.
Inputs:
txid - string; Transaction ID used to find the transfer.
account_index - unsigned int; (Optional) Index of the account to query for the transfer.
Outputs:
transfer - JSON object containing payment information:
address - string; Address that transferred the funds. Base58 representation of the public keys.
amount - unsigned int; Amount of this transfer.
confirmations - unsigned int; Number of block mined since the block containing this transaction (or block height at which the transaction should be added to a block if not yet confirmed).
destinations - array of JSON objects containing transfer destinations:
amount - unsigned int; Amount transferred to this destination.
address - string; Address for this destination. Base58 representation of the public keys.
double_spend_seen - boolean; True if the key image(s) for the transfer have been seen before.
fee - unsigned int; Transaction fee for this transfer.
height - unsigned int; Height of the first block that confirmed this transfer.
note - string; Note about this transfer.
payment_id - string; Payment ID for this transfer.
subaddr_index - JSON object containing the major & minor subaddress index:
major - unsigned int; Account index for the subaddress.
minor - unsigned int; Index of the subaddress under the account.
suggested_confirmations_threshold - unsigned int; Estimation of the confirmations needed for the transaction to be included in a block.
timestamp - unsigned int; POSIX timestamp for the block that confirmed this transfer (or timestamp submission if not mined yet).
txid - string; Transaction ID of this transfer (same as input TXID).
type - string; Type of transfer, one of the following: "in", "out", "pending", "failed", "pool"
unlock_time - unsigned int; Number of blocks until transfer is safely spendable.
Example:
Sign a string.
Alias: None.
Inputs:
data - string; Anything you need to sign.
Outputs:
signature - string; Signature generated against the "data" and the account public address.
Example:
Verify a signature on a string.
Alias: None.
Inputs:
data - string; What should have been signed.
address - string; Public address of the wallet used to sign
the data.
signature - string; signature generated by sign
method.
Outputs:
good - boolean;
Example:
Export all outputs in hex format.
Alias: None.
Inputs: None.
Outputs:
outputs_data_hex - string; wallet outputs in hex format.
Example:
Import outputs in hex format.
Alias: None.
Inputs:
outputs_data_hex - string; wallet outputs in hex format.
Outputs:
num_imported - unsigned int; number of outputs imported.
Example:
Export a signed set of key images.
Alias: None.
Inputs: None.
Outputs:
signed_key_images - array of signed key images:
key_image - string;
signature - string;
Example:
Import signed key images list and verify their spent status.
Alias: None.
Inputs:
signed_key_images - array of signed key images:
key_image - string;
signature - string;
Outputs:
height - unsigned int;
spent - unsigned int; Amount (in atomic units) spent from those key images.
unspent - unsigned int; Amount (in atomic units) still available from those key images.
Example:
Create a payment URI using the official URI spec.
Alias: None.
Inputs:
address - string; Wallet address
amount - unsigned int; (optional) the integer amount to receive, in atomicunits
payment_id - string; (optional) 16 or 64 character hexadecimal payment id
recipient_name - string; (optional) name of the payment recipient
tx_description - string; (optional) Description of the reason for the tx
Outputs:
uri - string; This contains all the payment input information as a properly formatted payment URI
Example:
Parse a payment URI to get payment information.
Alias: None.
Inputs:
uri - string; This contains all the payment input information as a properly formatted payment URI
Outputs:
uri - JSON object containing payment information:
address - string; Wallet address
amount - unsigned int; Decimal amount to receive, in coin units (0 if not provided)
payment_id - string; 16 or 64 character hexadecimal payment id (empty if not provided)
recipient_name - string; Name of the payment recipient (empty if not provided)
tx_description - string; Description of the reason for the tx (empty if not provided)
Example:
Retrieves entries from the address book.
Alias: None.
Inputs:
entries - array of unsigned int; indices of the requested address book entries
Outputs:
entries - array of entries:
address - string; Public address of the entry
description - string; Description of this address entry
index - unsigned int;
payment_id - string;
Example:
Add an entry to the address book.
Alias: None.
Inputs:
address - string;
payment_id - (optional) string, defaults to "0000000000000000000000000000000000000000000000000000000000000000";
description - (optional) string, defaults to "";
Outputs:
index - unsigned int; The index of the address book entry.
Example:
Delete an entry from the address book.
Alias: None.
Inputs:
index - unsigned int; The index of the address book entry.
Outputs: None.
Example:
Refresh a wallet after opening.
Alias: None.
Inputs:
start_height - unsigned int; (Optional) The block height from which to start refreshing.
Outputs:
blocks_fetched - unsigned int; Number of new blocks scanned.
received_money - boolean; States if transactions to the wallet have been found in the blocks.
Example:
Rescan the blockchain for spent outputs.
Alias: None.
Inputs: None.
Outputs: None.
Example:
Get a list of available languages for your wallet's seed.
Alias: None.
Inputs: None.
Outputs:
languages - array of string; List of available languages
Example:
Create a new wallet. You need to have set the argument "–wallet-dir" when launching oxen-wallet-rpc to make this work.
Alias: None.
Inputs:
filename - string; Wallet file name.
password - string; (Optional) password to protect the wallet.
language - string; Language for your wallets' seed.
Outputs: None.
Example:
Open a wallet. You need to have set the argument "–wallet-dir" when launching oxen-wallet-rpc to make this work.
Alias: None.
Inputs:
filename - string; wallet name stored in –wallet-dir.
password - string; (Optional) only needed if the wallet has a password defined.
Outputs: None.
Example:
Close the currently opened wallet, after trying to save it.
Alias: None.
Inputs: None.
Outputs: None.
Example:
Change a wallet password.
Alias: None.
Inputs:
old_password - string; (Optional) Current wallet password, if defined.
new_password - string; (Optional) New wallet password, if not blank.
Outputs: None.
Example:
Check if a wallet is a multisig one.
Alias: None.
Inputs: None.
Outputs:
multisig - boolean; States if the wallet is multisig
ready - boolean;
threshold - unsigned int; Amount of signature needed to sign a transfer.
total - unsigned int; Total amount of signature in the multisig wallet.
Example for a non-multisig wallet:
Example for a multisig wallet:
Prepare a wallet for multisig by generating a multisig string to share with peers.
Alias: None.
Inputs: None.
Outputs:
multisig_info - string; Multisig string to share with peers to create the multisig wallet.
Example:
Make a wallet multisig by importing peers multisig string.
Alias: None.
Inputs:
multisig_info - array of string; List of multisig string from peers.
threshold - unsigned int; Amount of signatures needed to sign a transfer. Must be less or equal than the amount of signature in multisig_info
.
password - string; Wallet password
Outputs:
address - string; multisig wallet address.
multisig_info - string; Multisig string to share with peers to create the multisig wallet (extra step for N-1/N wallets).
Example for 2/2 Multisig Wallet:
Example for 2/3 Multisig Wallet:
Export multisig info for other participants.
Alias: None.
Inputs: None.
Outputs:
info - string; Multisig info in hex format for other participants.
Example:
Import multisig info from other participants.
Alias: None.
Inputs:
info - array of string; List of multisig info in hex format from other participants.
Outputs:
n_outputs - unsigned int; Number of outputs signed with those multisig info.
Example:
Turn this wallet into a multisig wallet, extra step for N-1/N wallets.
Alias: None.
Inputs:
multisig_info - array of string; List of multisig string from peers.
password - string; Wallet password
Outputs:
address - string; multisig wallet address.
Example:
Sign a transaction in multisig.
Alias: None.
Inputs:
tx_data_hex - string; Multisig transaction in hex format, as returned by transfer
under multisig_txset
.
Outputs:
tx_data_hex - string; Multisig transaction in hex format.
tx_hash_list - array of string; List of transaction Hash.
Example:
Submit a signed multisig transaction.
Alias: None.
Inputs:
tx_data_hex - string; Multisig transaction in hex format, as returned by sign_multisig
under tx_data_hex
.
Outputs:
tx_hash_list - array of string; List of transaction Hash.
Example:
Get RPC version Major & Minor integer-format, where Major is the first 16 bits and Minor the last 16 bits.
Alias: None.
Inputs: None.
Outputs:
version - unsigned int; RPC version, formatted with Major * 2^16 + Minor
(Major encoded over the first 16 bits, and Minor over the last 16 bits).
Example:
Reworked GetMonero.org RPC calls for Oxen under their copyright license.
The ONS namespace is broken up into two distinct sections. One section is responsible for all Lokinet names, referred to as .loki
names, and the other section is responsible for Wallet and Session usernames.
Each ONS name can resolve to a Session public key, Wallet address or .loki
address. Session and Wallet names are within the same namespace. When purchasing a Session record, the Wallet record is automatically added to your possession. Lokinet names are in their own namespaces. For example, when purchasing ‘KeeJef’ in the Session namespace, you can assign a Session public key. Additionally you can update the wallet record under a 2nd transaction.
So when a user looks up ‘KeeJef’ they are returned both a Account ID and Wallet address:
It is also possible to purchase ‘KeeJef.loki’ in the Lokinet namespace that is unique from the Session and Wallet namespace.
Depending on which context the name is being used, the application will automatically use the relevant mapping.
Both namespaces (Session/Wallet and Lokinet) have restrictions on the characters allowed in a name. All names are case-insensitive.
For Session (or Wallet), the name has to:
start with an alphanumeric character or underscore
consist of alphanumeric, hyphens or underscores in between
end with an alphanumeric character or underscore
Users may register names with special characters or emojis by using the equivalent Punycode representation. The name must be at least 1 character long, and at most, 64 characters long.
For Lokinet, the domain must:
start with an alphanumeric character
contain alphanumeric characters or hyphens
The character before the domain suffix .loki
must be alphanumeric followed by the suffix .loki
. Users may register names with special characters or emojis by using the equivalent Punycode representation. The domain name must be at most 253 characters long, including the .loki
suffix.
By default all mappings in the Session/Wallet namespace will be preserved forever. This is important to ensure that wallet mappings don't change when a user wants to send money to a name. The .loki
namespace will have re-registration periods to deter domain squatting and release names if the keys that registered them are lost.
By default names are owned by the wallet address that purchased the name. However, names can also be purchased on behalf of another user. Up to 2 wallet addresses may be specified as the owners of a name. This means up to 2 wallets can update and or transfer ownership of the record.
Once a name it can be transferred to another user's Oxen wallet by specifying the address of that wallet and paying the standard transaction fee to transfer the ownership.
Updates to mappings can be made at any time by the owner, at the cost of the standard transaction fee to include the new mapping in the blockchain.
Initially, management of all owned names will be possible through the Oxen Desktop Wallet; however we aim to add functionality to register and manage names to Session clients directly in the future.
Names in the Session/Wallet namespace cost 7 $OXEN to register. We will try to update this cost per hardfork to continue targeting the $5-10 USD range.
It is up to each user to choose which information they map publicly. If you don’t want to map your Account ID or Wallet address to your real world identity you might want to choose a different alias instead of something related to your name. Basic encryption is employed to mask publicity of data on the surface level, but please do not rely on this for critical privacy requirements.
All wallet sub-addresses generated via account new are supported as owners.
ONS records stored in the blockchain undergo basic encryption and decryption to deter monitoring of the chain. This does not provide strong guarantees for privacy and should not be relied on for situations with critical privacy requirements.
At its core, a typical ONS record from the database looks like:
name_hashed
encrypted_value
register_height
owner
backup_owner
txid
prev_txid
register_height
more fields (implementation details, see oxen_name_system.h)
Of which the name_hashed
and encrypted_value
fields use some form of encryption or decryption.
name_hashed
Human readable name is hashed with blake2b
with the following parameters
Key Length: 0 bytes
Hash Length: 32 bytes
Name hash converted to base64 for storage into the sqlite3
database (this provides optimal lexicographic lookup as a key).
encrypted_value
Generate the secret key for decryption/encryption using the unhashed name with Argon2ID v1.3
and the following parameters as of Valiant Vidar v7.1.X
Iterations: 3
Memory: 268_435_456 bytes
Salt Length: 0 bytes
Key Length: 32 bytes
Decrypt/encrypt the value represented in binary with XSalsa20Poly1305
and the following parameters as of Valiant Vidar v7.1.X
Nonce: 0 bytes
In ONS, an owner of a record has the ability to update information about the record by making a transaction on the Oxen blockchain. Owners are specified when buying a record and in ONS we support 2 types. A standard Ed25519 keypair and an Oxen Wallet address.
By default, the wallet is configured to assign itself as the owner of the mapping when purchased.
ONS records can be updated by getting the owner of the record to generate a signature that authorises the protocol to update fields in the record.
The following fields can be updated in a record
Copy the fields to update into a buffer
Copy the TXID into the buffer that last updated the record (which can be retrieved by querying the mapping).
Hash the buffer with blake2b
with the following parameters
Key Length: 0 bytes
Hash Length: 32 bytes
Sign the hashed buffer
If the current owner (or backup owner) is a wallet address, it must be signed with the current owner's (or backup owner's) wallet secret spend key.
If the current owner (or backup owner) is a ed25519 key, it must be signed with the current owner's (or backup owner's) ed25519 secret key.
Although service nodes have the ability to store data on behalf of clients, this responsibility only extends so far. Requiring service nodes to store attachments, which can easily be orders of magnitude larger than messages (and might need to be stored for longer periods of time) would place an undue burden on the service node network.
With this in mind, a logical solution is for Session to interface with an untrusted centralised server that stores data obliviously. As long as the central server cannot know the contents of files, or who is storing and requesting the files, this system does not cause any metadata leakage.
This is achieved by first padding each attachment to fit within a fixed number of constant sizes between 0 and 10 megabytes, then encrypting the attachment with a random symmetric AES key. The sender then uploads the encrypted file using an onion request. In response, the file server provides a link to the piece of content, returned via the onion request path.
Once the sender obtains this link, they then send a message to the recipient via an existing pairwise session. This message contains a link to the content, a hash of the content, and the decryption key. The recipient then uses an onion request to pull the encrypted attachment from the centralised file server and decrypt it locally using the decryption key provided by the sender. The recipient also checks the hash against the attachment, ensuring the file has not been modified in transit.
By default, all Session clients use a Session file server run by the Oxen Privacy Tech Foundation for attachment sending and storage. Since attachments are not considered a core feature of Session, this design is in keeping with Session's design principles. The file server is fully open-source, with setup instructions provided so that users are able to set up their own file server. In an upcoming update users will be able to specify in the Session client which file server they want to use for attachment sending functionality. This is important both for providing users with choice and control, and ensuring the continued usefulness and functionality of Session if the OPTF were no longer able to maintain the default Session file server.
First add the oxen.io apt repository to your system:
Update your apt package list:
Install the lokinet-gui
package:
This will also install and start a background service called lokinet.service
that can be controlled with the lokinet-gui application.
Simply jump into the lokinet-gui client and click the large green power button.
Head over to Exit nodes or Accessing SNApps for an overview of the exciting things you can do with Lokinet up and running!
See the troubleshooting guide here if you have issues.
Begin by updating your package lists. The below command downloads package lists from your repositories and "updates" them to get information on the newest versions of packages and their dependencies. It will do this for all repositories and PPAs.
Run the following command:
You'll notice a bunch of package lists were downloaded. Once this is complete, run the below command to fetch new versions of any packages we currently have installed on the system:
You'll be prompted to authorise the use of disk space. Type y
and press Enter to authorise.
If you do not have curl
installed on your computer, now is also a good time to install it, as we will use it later:
You only need to do this step the first time you want to set up the Lokinet repository. After you've done it once, the repository will automatically update whenever you fetch new system updates.
This first command installs the public key used to sign official Lokinet binaries.
The next command tells apt
where to find the packages:
Note: if you're running Linux Mint and get an error with this command, check out Troubleshooting.
Then resync your package repositories with:
Now install Lokinet:
Congratulations, Lokinet is now installed and running in the background.
By default, lokinet will be running in the background on boot.
You can disable lokinet from starting on boot with:
You can re-enable lokinet to run on boot with:
You can stop the lokinet service with:
You can use stop, start or restart to start and stop lokinet using the command above replacing stop
with start
or restart
To update Lokinet when installed with apt run the following command:
Head over to Exit nodes or Accessing SNApps for an overview of the exciting things you can do with Lokinet up and running!
If lokinet gets "stuck" trying to connect to the network, back up any persisting private keys for .loki and....
stop the lokinet service
remove /var/lib/lokinet/profiles.dat
start the lokinet service
this will remove the client's inferred network state that it slowly generates over time, thus will start retrying nodes it thought were dead before.
It has been reported that Linux Mint users may need to use the following command instead of the second command in 2. Installation:
Run the downloaded .exe file
Check both "lokinet" and "gui" in the installer and then click "install"
Run the application
Press the big power button in the Lokinet interface to start or stop Lokinet
All done!
Head over to Exit nodes or Accessing SNApps for an overview of the exciting things you can do with Lokinet up and running!
To uninstall Lokinet on Windows, open control panel and navigate to "Uninstall a Program", then find Lokinet and click uninstall.
Latest Oxen Service Node software |
Server operating system | Ubuntu 20.04+ (latest LTS recommended) or Debian 11+ (latest stable recommended) |
Storage | 40GB or more |
RAM | 4-8GB (4GB absolute minimum) |
Connectivity | 100Mb or faster |
Traffic | 1TB per month or more |
Power | Redundant with remote cycling ability, as found in most data centres |
How to configure a server as an Oxen Service Node (quickly) |
How to configure a server as an Oxen Service Node (in depth) |
How to stake to an Oxen Service Node using the Oxen GUI Wallet. |
Explanation of the conditions under which a service node may be deregistered (removed from the network), and some tips on how to avoid deregistration. |
Some handy tips and tools for maintaining your Oxen Service Node. |
Session open groups servers (SOGS) are group chat servers that can host thousands of chat participants. This guide explains how to set up a Session open group server.
Note: Session open group servers provide transit encryption, but open group messages are not encrypted while stored on the server; closed groups (which can be created within Session itself) are a better solution for high-security communications with groups of 100 or less people.
Open groups are hosted using PySOGS. Written in Python, PySOGS is the reference implementation of a Session open group server. PySOGS is used to run the official Session open groups, and is the officially supported open group server.
Below you can find a video guide walking you through the process of setting up a Session open group server, as well as a written guide.
Note: .debs for the Session Open Group server are currently available for Ubuntu 20.04 and newer, and for Debian 10 and newer. For other operating systems, you can build from source
Typically, the simplest and cheapest way to host a server is by leasing a Virtual Private Server (VPS). There are hundreds of VPS providers to choose from, some popular options are: Vultr, Hetzner, DigitalOcean, Linode, Amazon Lightsail, etc.
You can run a SOGS from home, but consider most consumer internet connections have poor upstream bandwidth, typically don't provide a static IP address, and transient power and network outages are a relatively common. These factors can affect the stability of your SOGS and the ability for users to chat in your group.
Resource requirements are highly dependent on how many users you plan to support in your open groups and how frequent usage is, however, a good starting point would be:
1 Virtual core, 512 MB of RAM, 20GB HDD space
Once you have signed up for a provider you should receive a static IP address, you will need to SSH into your server, you can find instructions on how to do this online.
Add the Oxen apt repository by running the following commands
You have a choice to install either the sogs-standalone package or the sogs-proxied package.
This is the simple SOGS package for most setups. It installs a SOGS that listens on a public IP/port for HTTP connections. It does not support HTTPS connections (but since all messages to/from SOGS are separately encrypted, HTTPS is not necessary nor recommended).
This package provides a more advanced SOGS configuration where SOGS itself will listen on an internal port and expects to have requests proxied to it from an ngnix or apache2 front-end server that listens on the public IP/port. The package will install basic site configuration files for either nginx or apache2, but extra configuration may be necessary.
This package is required if you want your SOGS to be reached over HTTPS: the HTTPS handling is configured on the front-end server (i.e. in nginx or apache) using a tool such as certbot
. (This package does not auto-configure such HTTPS certificates, but there are many online help pages on setting up such HTTPS support for a front-end web server).
If you don't know what any of this means then stick with the sogs-standalone
package.
OR
If installing the standalone version you will see this prompt, asking you to enter a URL or IP address, if you have not setup DNS to point towards the IP address of your VPS then you should enter your VPS Public IP address, which can usually be found on your VPS provider's website.
Once finished with installation, you will want to add a room, to add a room run:
Replace TOKEN
with the address to use in the room URL (which must consist of ONLY lowercase letters, numbers, underscores, or dashes), replace NAME
with the room name to display in Session and optionally replace DESCRIPTION
with a short description of the topic of the room.
As an example, setting up a room for discussion of Australian fisheries
Make yourself a global administrator for all rooms hosted on your SOGS by running the following:
Replace SESSIONID
with the Account ID you want to be an administrator
For example:
Once setup, you should be able to navigate to your VPS's IP address in a web browser, for example http://116.203.70.33/
Here you should see a list of your rooms, clicking on a room will display a QR code and the link required to join the room, this link can be copied and pasted into a Session client to join a group.
SOGS is configured as a Debian package, it will be updated when you update and upgrade other packages on your system, you can trigger this process by running the following commands
If you're having trouble setting up your SOGS, we recommend opening an issue on the Session open group server GitHub repository. Contributors to the PySOGS software should be able to assist you in getting everything up and running.
Lokinet is open-source software which uses the Oxen Service Node network to operate a low-latency onion routing protocol. This allows users to browse the web without the destination or origin of data packets being exposed via Lokinet exit nodes, as well as accessing internally-hosted services called SNApps.
Lokinet is an open-source, fully decentralised overlay network which allows users to browse the internet privately and securely, as well as access services (called SNApps) hosted on Lokinet. Lokinet achieves this through use of a low-latency onion routing protocol (LLARP) designed as a hybrid between I2P and Tor, while providing additional benefits.
When using Lokinet to browse the internet, encrypted data packets are routed through multiple service nodes. No single node ever knows the full path your data takes, so you can browse with true anonymity. Since these nodes are part of the Oxen network, they are also required (and economically incentivised) to provide high-quality service, unlike onion routers like Tor which rely on volunteers.
Lokinet also provides the benefit of being protocol-agnostic — while competing onion routers operate on the transport layer and are only able to carry TCP traffic, Lokinet operates on the network layer and is therefore able to onion-route any IP-based protocol: TCP, UDP, ICMP, etc. In plainer terms, this means Lokinet can relay real-time voice and video calls, video streams, and other high-bandwidth content which simply can't be routed over other onion routers.
To download Lokinet, head over to the Lokinet website.
Session follows one of two distinct cases for message routing, depending on the availability of participating clients:
By default, or when either of the participating clients' statuses is determined as offline (see Synchronous Routing for how client status is determined), Session will use asynchronous routing. In asynchronous routing, the sender determines the recipient's swarm by obtaining the deterministic mapping between the recipient's long-term public key and the currently registered Oxen Service Nodes. This information is initially requested from a random service node by the sender and updated whenever the client gets an error message in the response that indicates a missing swarm.
Once this mapping is determined, the sender creates the message protobuf and packs the protobuf in an envelope with the information to be processed by service nodes: the long-term public key of the recipient, a timestamp, TTL ("time to live") and a nonce which proves the completion of the required proof of work. The sender then sends the envelope using an onion request to one or more random service nodes within the target swarm (in practice, each request is always sent to 3 service nodes to achieve a high degree of redundancy). These service nodes then propagate the message to the remaining nodes in the swarm, and each service node stores the message for the duration of its specified TTL.
Alice uses an onion request to communicate with three random service nodes in Bob’s swarm. Bob then uses an onion request to retrieve said message, by talking to three random service nodes in his swarm.
Session clients include their online status in the encrypted protobuf of any asynchronous message they send. Along with their online status, a sending client also lists an Oxen Service Node in their swarm to which they are listening via onion request.
When a Session client receives a message which signals the online status of another client, the receiver sends an onion request to the sender's specified listening node. The recipient also exposes their own listening node to the sender. If this process is successful, both sender and receiver will have knowledge of each others' online status and corresponding listening nodes. Messages may now be sent synchronously through onion requests to the conversing clients' respective listening nodes.
Alice uses an onion request to send a message to Bob’s listening node. Bob receives this message using an onion request, then sends a message to Alice’s listening node.
Messages sent using this synchronous method do not contain proof of work, and listening nodes do not replicate or store messages. To ensure messages are not lost, receiving clients send acknowledgements after receipt of each message. If either device goes offline, this acknowledgement will not be received, and the client which is still online will fall back to using the above asynchronous method of message transmission.
Friend requests are sent the first time a client initiates communication with a new contact. Friend requests contain a short message with a written introduction, the sender's prekey bundle, and meta-information like the sender's display name and public key, which the recipient can use to respond. Friend requests are encrypted for the public key of the recipient using ECDH. When a friend request is received, the client can choose whether to accept it. Upon acceptance, the client can use the prekey bundle to begin a session and start sending messages asynchronously.
Lokinet's exit node functionality allows you to browse the normal Internet (the 'clearnet') with all the privacy and security protections Lokinet provides. To use an exit node, all you need is a working Lokinet client and an exit node address (the OPTF is currently operating a test exit node available at exit.loki
, suitable for basic web browsing).
Using exit nodes with the Lokinet GUI client is as easy as 1, 2, 3!
Open the Lokinet Control Panel and enter the address of the exit node you'd like to use (e.g. exit.loki
) in the Exit Node box:
Some exit nodes may require an authentication code (password) to use (note: exit.loki
does not require an authentication code). If the exit node you're using requires an authentication code, enter it in the Auth Code box:
With your exit address and auth code (if applicable) entered, all you need to do is click the switch next to Enable Exit:
Now turn on Lokinet (if not already on) with the big green power button, and you're ready to browse the internet with all the privacy protections of Lokinet.
To begin browsing from an exit node, use the following command, replacing EXITNODEADDRESS.loki with the address of your desired exit node:
To disable exit node functionality:
Accessing SNApps is as simple as , opening your browser of choice, and entering the SNApp's .loki address in the address bar!
Jump into a browser such as Chrome or Firefox and enter the following SNApp address:
This should take you to the Lokinet Wiki, hosted within Lokinet. If this SNApp works, you have full Lokinet access!
Depending on the nature of the application or service which you want to make accessible over Lokinet, you may want to only run a temporary SNApp, or a SNApp that continues to persistently use the same .loki pubkey.
A temporary SNApp is a service accessible over Lokinet that does not have a permanent address. This means that the address you supply to others will not work once the server hosting the SNApp is restarted.
If you want users to be able to access your application or service over an extended period of time, a temporary SNApp is not recommended.
If you only want to host a temporary SNApp, jump to .
Note: This guide assumes you are running a standard Debian or Ubuntu Linux distribution on the machine on which you'll be hosting the SNApp and that you have Lokinet installed and running on this machine, if not please follow the guide to get Lokinet running. This guide also assumes you are relatively familiar with using the command line.
Start by opening your lokinet.ini
file and adding a path to where your SNApp key files will be stored.
If you have installed Lokinet from Deb packages, you can open your lokinet.ini
file in the nano
text editor with the following command:
Otherwise, if you have built Lokinet from source, your lokinet.ini
file will be in the folder ~/.lokinet/lokinet.ini
, and can be opened in nano
with the following command:
With lokinet.ini
open in the text editor, scroll down to your [network]
section and add the following line:
Alternatively, you can set the filepath to wherever you want your SNApp private key to be stored.
Now, when you restart Lokinet, it will generate your snappkey.private
file in the directory you have set.
You can find your SNApp's current address using a host lookup tool:
You can also use the host
command (the .loki address to query is the same, but the resolver uses the address 127.3.2.1
as to not conflict with other resolvers you may have installed):
Install a proper web server:
If you want your SNApp to be accessible only via Lokinet and not via your IP address or domain name then you will need to configure nginx
to run only on the lokinet interface.
this can go underneath your existing network config changes, after this change is made restart Lokinet using:
Once Lokinet is restarted run the following command to open your nginx default configuration file, we are going to make a few changes here.
This should leave your default file in sites available looking something like this:
save the changes and exit the file. Once this step is complete you can reload nginx with the following command:
Setup a clearnet and Lokinet accessible SNApp
If you want your SNApp to be accessible via Lokinet and your clearnet IP/Domain name then fewer changes are required. First open /etc/nginx/sites-enabled/default
using:
TIP: By default, you can drop files into /var/www/html
to serve them as a SNApp. Make sure they are accessible via the www-data
user (or whichever user nginx
runs as.
TIP: You can make nginx
generate a directory listing of files by adding autoindex on;
on a new line into the location
block in the nginx config file.
Make sure no services bind to all interfaces.
Lokinet SNApps allow users to interact with applications or services entirely within Lokinet, similar to Tor's hidden services. SNApps provide an even higher degree of anonymity than can be achieved when accessing externally hosted content through . SNApps allow for users to set up and host marketplaces, forums, whistle-blowing websites, social media sites, and other web-based applications on their own servers while maintaining full server- and client-side anonymity. SNApps greatly expand what's possible with Lokinet, and allow users to build meaningful communities entirely within Lokinet itself.
SNApp operators use the traditional server-client model, with the key difference being that act as intermediaries in a user's connection to the SNApp server. When a SNApp wishes to register on the network, it must update the DHT with its descriptor. This descriptor contains various introducers, which are specific Oxen Service Nodes that users can contact to form a path to the SNApp. When these paths are set up, users can connect to the SNApp without either party knowing where the other is located in the network.
A Guide on how to install Lokinet with the updated GUI
Thanks for downloading Lokinet on MacOS. This guide will help you install Lokinet.
Latest releases can be found and downloaded here
Open the .dmg file in your downloads directory (or wherever you downloaded Lokinet).
Select agree to agree to the GNU GPLv3 license agreement.
Drag and drop the Lokinet application into the applications folder.
Start the Lokinet application from the “Applications” folder and click open when prompted.
Once Lokinet is open, press the power button to turn Lokinet on. You will be prompted with a ‘System Extension Blocked’ popup, click ‘Open Security Preferences’.
If you do not see this popup, open System Preferences and navigate to Security & Privacy instead.
With the Security & Privacy settings window open, click the padlock in the bottom left corner.
After the padlock unlocks, click ‘Allow’, allowing Lokinet to load a system extension which is necessary for VPN functionality.
Enter your password and press unlock when prompted.
Once System Preference changes are allowed, a system prompt will appear. Click “Allow” to allow Lokinet to add a VPN Configuration.
Congratulations! You’re all done. Lokinet should now automatically start, if not try pressing the on button again and Lokinet should startup.
You can view, check, or alter the VPN Configuration created by Lokinet by opening System Preferences and navigating to Network.
Select agree to agree to the GNU GPLv3 license agreement.
Drag and drop the Lokinet application into the applications folder.
Start the Lokinet application from the “Applications” folder and click open when prompted.
Once Lokinet is open, press the power button to turn Lokinet on. You will be prompted with a ‘System Extension Blocked’ popup, click ‘Open Security Preferences’.
If you do not see this popup, open System Preferences and navigate to Privacy & Security menu instead.
click ‘Allow’, allowing Lokinet to load a system extension which is necessary for VPN functionality.
Enter your password and press unlock when prompted.
Once System Preference changes are allowed, a system prompt will appear. Click “Allow” to allow Lokinet to add a VPN Configuration.
Congratulations! You’re all done. Lokinet should now automatically start, if not try pressing the on button again and Lokinet should startup.
You can view, check, or alter the VPN Configuration created by Lokinet by opening System Preferences and navigating to Network.
Common issues with macOS
Lokinet is not turning on when i press the start button
Go to System Preferences / Security & Privacy settings and press the lock to make changes
See if there are any pending requests from Lokinet, if so make sure you allow any Lokinet requests.
If there are no requests, try starting the Lokinet app again and see if a request shows up on the Security & Privacy page
If you're having issues with resolving .loki addresses, you need to edit your resolv.conf files and add your DNS resolver.
Method 1
Install systemd-resolved
and let that manage dns.
Method 2
Install resolvconf
and let that manage dns.
Then restart lokinet.service
with systemd.
If resolvconf by itself doesn't work, you'll need to add the Lokinet nameserver manually to resolvconf.
Add the following line at the bottom of this file:
Once that line is added, hold Ctrl and type X, then type Enter to confirm the file changes.
Next we need to update our /etc/resolv.conf file by running the command:
Then restart lokinet.service
with systemd.
As of 0.9.11
there is an issue where sometimes lokinet will get into a bad state and refuse to connect to the network.
This case is not related network censors blocking lokinet, it's a bug. see https://github.com/oxen-io/lokinet/issues/2116
If this happens, makes ure you back up any persisting private keys for .loki and....
stop the lokinet service
remove /var/lib/lokinet/profiles.dat
start the lokinet service
This will remove the client's inferred network state that it slowly generates over time, thus will start retrying nodes it thought were dead before.
Mumble is a fantastic open-source voice chat platform known for its reliability and ease of use.
And Lokinet is a cutting-edge onion routing network that offers unparalleled security and anonymity potential.
In this guide, we’re going to show you how to run a Mumble server over Lokinet, combining Mumble’s ease of use with Lokinet’s security and anonymity to create the ultimate secure voice chat service. With just 15 minutes of your time and $3 a month, you or your organisation can create one of the most secure voice chat platforms possible.
A Mumble server running over Lokinet on a server you control gives you absolute certainty that your voice conversations, associated metadata, and other Mumble activity cannot be stored or recorded, because no computer ever knows who is talking to whom — not even the Mumble server itself. So long as you trust the device that you run the Mumble server on (which you can, because it’s yours), you can be certain that no one else on earth can eavesdrop on your conversation — or even know that you’re connected to the server at all.
If this is your first time using SSH and the Linux command line, don’t stress. We’ll walk you through every step! With that, let’s get to it.
The first thing you’ll want to do is rent yourself a VPS (Virtual Private Server) to host your Mumble voice chat server. You could run the Mumble server from your own computer instead, but if you want the server to stay up 24/7, without having to leave your own PC on all the time, a VPS is the way to go. Mumble’s chat server has extremely low system requirements, so a VPS with any amount of storage and at least 512MB RAM will do the trick — you can find VPSs that meet these requirements for around US$3 a month.
Try , or if you want to pay in $OXEN! When ordering, select Ubuntu 22.04 or Debian 11 as the operating system.
Once you have access to your new VPS, you’re almost ready to install Lokinet, but there’s a little bit of preparatory work to do first. Start by opening a command prompt on your local machine (Terminal on macOS, any command prompt on Linux, or PowerShell on Windows 10). SSH into (get remote access to) your VPS with this command:
ssh root@
[VPS IP address]
Replacing [VPS IP address]
with the IP of your VPS. It’ll prompt you for a password which will usually be provided to you by the VPS host. More advanced users can and should disable root password access and instead use SSH keys, but if that sounds hard, don’t worry about it for now. As you learn more about Linux, you’ll get more familiar with these best practices.
Once you’ve logged in, we’re ready to roll. First, we’ll update our package lists to make sure our VPS sees the most recent versions of all available packages. Type:
sudo apt update
You’ll see a bunch of package lists being downloaded. Once this command completes, run the following command to upgrade any outdated packages currently installed on the VPS:
sudo apt upgrade
We’ll also need to make sure the curl
command is installed before we proceed. Run this command:
which curl
It should output the location of your installed curl command. If you get an error, install curl
:
sudo apt install curl
Then run which curl
again to make sure curl
is installed.
Success? Congrats, you’re ready to move on to the next step:
To install Lokinet, we need to add the Lokinet repository. Run the following command to install the public key used by the Lokinet dev team to sign Lokinet binaries:
sudo curl -so /etc/apt/trusted.gpg.d/oxen.gpg https://deb.oxen.io/pub.gpg
Then run the following command to tell apt
where to find the Lokinet packages:
echo "deb https://deb.oxen.io $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/oxen.list
Next, update your repository package lists again with:
sudo apt update
And now, install Lokinet:
sudo apt install lokinet
Congrats, Lokinet is now installed and running in the background. We’re nearly there.
Run this command:
sudo apt install mumble-server
That’s it. The Mumble server is now installed. On to Step 5:
This step is a bit more involved. We need to set up Lokinet to always generate a keyfile in the same directory, so it will work consistently. Linux servers don’t have a graphical interface, but they do ship with some in-terminal text editors. We need to edit a file now, so start by opening your lokinet.ini
file with this command:
sudo nano /etc/loki/lokinet.ini
Using the arrow keys, move the cursor down to the [network] section of the file. Remove the # from before the “keyfile=” line, then add the following after the = symbol:
/var/lib/lokinet/mumble.private
Then hit Ctrl+X. Type “Y” (for yes) when asked if you want to save your changes, then press Enter to save and exit.
Now that you’ve exited nano
, you’re back in the terminal. Restart Lokinet to generate a keyfile for Mumble:
sudo systemctl restart lokinet
Now we need to make sure your Mumble server is using Lokinet for all traffic. Start with this command to grab the IP address we need to bind Mumble to:
dig @127.3.2.1 +short localhost.loki
This command will output 2 strings of text: a long string of random letters and numbers ending in .loki, and an IP address (a number in the format xxx.xx(x).x.x).
Select and copy (Ctrl+C on Windows or Linux; Cmd+C on macOS) the IP address. Some SSH clients allow you to copy by highlighting the text and right-clicking on it as well.
Now, we need to point the Mumble server to that IP address. Use this command to open the configuration file for the Mumble server:
nano /etc/mumble-server.ini
Using the arrow keys, navigate down to the line “;host=”
under the section Specific IP or hostname to bind to. Delete the ;
from the start of the line, then paste the IP address we copied earlier after the =
symbol. Hit Ctrl+X to exit. Type “Y” when asked if you want to save your changes, then press Enter to save and exit.
Back at the command line, restart the Mumble server to apply changes:
systemctl restart mumble-server
Congrats! A Mumble server is now up and running on your VPS, and all its traffic is being routed through Lokinet. All that’s left is to grab the Lokinet address of the Mumble server and give it to anyone you want to be able to connect. In case you missed it, run this command to find the Lokinet address of the Mumble server:
dig @127.3.2.1 +short localhost.loki
This is the same command we ran earlier, but this time, pay attention to the long string of characters ending in .loki (be sure to include the .loki part!). This is the Lokinet address of your secure, onion-routed Mumble server.
Copy this address and provide it to anyone you want to be able to connect to the server — all they have to do is paste the address into the Address field of the Add Server dialog in the Mumble client, add a username and label to identify the server, hit OK, and connect!
In the meantime, though, this Mumble/Lokinet setup is perhaps the most secure voice channel option available. This unique combination of services is just one example of the power of the Oxen tech stack — stay tuned for more guides and articles about what Oxen’s tech can do.
Have fun!
Latest Service Node .deb
packages (installed via the steps below) or latest
First we will need to set the Lokinet interface IP range, we can do this by accessing our Lokinet config file as we did in and adding this line in the [network]
section:
change any listen
directives to use the lokinet IP 10.67.0.1
remove any IPV6 listen
directives and replace the .loki address after server_name
with the Lokinet address you discovered in
Proceed to
Then add your .loki address (which you discovered in ) as a server_name
, after the changes your nginx default file should look something like this:
Proceed to
Suggested firewall settings when using nginx:
Congratulations! Your SNApp should now be accessible over Lokinet. Use the Lokinet address you discovered in , to access your SNApp
Mumble can be on all major platforms. Anyone that wants to access your secret Mumble server will also need to have Lokinet installed and running. To download and install Lokinet, just head to . Additional Lokinet guides can be found back at the here on Oxen Docs.
And that’s it! Only 15 minutes and $3 later, you can now have completely surveillance-free conversations over the internet. We hope to integrate voice features into to make it even easier to access secure voice channels with this level of privacy and security.
It is possible to configure your SNApp so that others can get service information when looking it up. For example, you may want to tell the user you are hosting an xmpp server at a specific port, or even at a different .loki address, or perhaps even load-balance a service across multiple .loki addresses.
To start open the Lokinet config file, If you have built Lokinet from Deb packages, you can open your lokinet.ini
file in the nano
text editor with the following command:
Otherwise, if you have built Lokinet from source, your lokinet.ini
file will be in the folder ~/.lokinet/lokinet.ini
, and can be opened in nano
with the following command:
Under the section heading [network]
add one or more entries with the following format:
An example:
This would be an entry for the XMPP protocol, pointing to mylokiaddress.loki
at port 1234.
Another example:
This would be an entry for Mumble, pointing to the SNApp you are configuring at port 64738.
The target in this entry MUST be one of the following:
empty, which means "just use the .loki for this SNApp"
a single dot (.
), which means "this SNApp does NOT have that service available"
any valid name in the .loki TLD.
For more information on SRV records and what you can do with them, visit the Wikipedia article.
Guide | Description |
How to access SNApps. |
Hosting your own SNApp (making a web service available over Lokinet). |
How to give your SNApp a human readable address |
How to add and configure SRV records for your SNApp |
This guide covers installing and configuring the Oxen CLI (Command Line Interface) Wallet on macOS.
If you are new to console or terminal commands and/or would prefer a wallet with buttons and Oxen branding, we suggest you download the GUI Wallet.
Before following the guide below, you'll need to download the CLI Wallet for macOS. This guide assumes you are running the latest version of macOS and have Xcode installed.
To use the oxen-wallet-cli
we must first have the daemon, oxend
, up and running. The oxend
is your node which the oxen-wallet-cli
broadcasts through. Without the node running the oxen-wallet-cli
will not be able to operate.
Open up the oxend
file in the folder you extracted the release from. In most cases you will have the following security dialog box pop up.
If the dialog box opens up you will need to allow the oxend
to open by moving your cursor to the top-left of your screen, clicking the apple logo, and then clicking on system preferences.
Once in System Preferences, click on the Security & Privacy
button, check in this new screen that the oxend
file was blocked, if it was you should be confident to click “Open Anyway”.
Keep clicking open
and allow
to give the software permission to run.
Once the software has permission a terminal window should pop up and say the following text:
Let the daemon run until the node is completely synced, you will know the node is synced once the terminal outputs the following text:
Now the daemon is synced we can run the oxen-wallet-cli
file.
If this is your first time opening the oxen-wallet-cli
it will request for you to specify a wallet name. For the purposes of this user guide we will use the example name MyWallet
Because this is the first time we have used the name MyWallet
the following text will appear in our terminal. Type in Y
or Yes
to confirm your wallet name.
The oxen-wallet-cli
has now generated us a wallet called MyWallet
and is now prompting us for a password for our generated wallet.
Please note:
When typing the password, the characters will not appear. It will seem as if you are typing and no text is appearing however the terminal is logging every character your clicking including if it is capitalised or lowercase.
Write down your wallet name and password on a piece of paper as this information will be required every time we want to enter our wallet.
Use a password with uppercase letters, lowercase letters, numbers, symbols and make the password at least 9 characters long.
Now once we have chosen our password for the wallet we must choose our language. For the purposes of this user guide I suggest you use English by typing 1
and clicking enter.
The oxen-wallet-cli
will generate and spit out several lines of text. Some of the information that was outputted will only ever show once, therefore it is very important to do this next section properly otherwise we may lose access to our account, thus losing access to our funds.
Let’s take a close look at each section of the newly generated wallet:
The text after Generated new wallet
shows your public address. This address can be shared and will be used to receive $OXEN to your wallet. All Oxen public addresses start with an L....
and are followed with a string of characters. The public address shown will be your primary address however multiple public addresses can be generated from this primary address.
You do not need to write down the public address, the command address
will re-display it whenever required.
The View key address is not to be shared unless you want to show the transactions received to the public address connected to this wallet. You do not need to write down the view key as it can be re-displayed with the command viewkey
.
The next few lines of text show how to navigate the oxen-wallet-client
.
The next section with the random 25 words is your mnemonic seed. The seed is used to easily back-up and restore your wallet without needing any other information. At this stage, grab a pen and paper and write down your 25 words in order (having these words out of order will not restore your wallet) and store the piece of paper in a safe and secure place. If your words are stored in a text file on your computer or stored online, you increase your risk of someone else getting control of your account.
The last of the outputs are the account balance, because your wallet does not have any $OXEN in it currently the balance is showing 0.
Once we receive a transaction of $OXEN into our wallet the balance will appear as soon as the transaction is confirmed in one block (usually less than 2 minutes). Once the transaction has been confirmed over 10 blocks the balance will show in unlocked balance.
The unlocked balance is the $OXEN available to be spent/sent to other addresses.
By default Lokinet uses 52 character non human readable strings as addresses in the network, for example:
http://dw68y1xhptqbhcm5s8aaaip6dbopykagig5q5u1za4c7pzxto77y.loki
These default addresses can be hard to remember and communicate to users.
ONS (Oxen Name Service) allows SNApp operators to map a human readable name to any default .loki address, as an example
http://probably.loki
Which is an ONS record mapping the human readable name probably
and the Lokinet address dw68y1xhptqbhcm5s8aaaip6dbopykagig5q5u1za4c7pzxto77y
ONS records are registered as transactions the Oxen blockchain and can be resolved by Lokinet clients, which with the Service Node network. They work in a similar manner to other blockchain naming services like ENS
Registering a .loki ONS mapping requires the user to create an Oxen wallet and deposit at least 7 Oxen (plus transactions fees), visit the Oxen website to find out where Oxen can be bought
You can register a ONS record by opening the "Oxen Name Service" tab in the Oxen GUI wallet
Once the "Oxen Name Service" tab is open, select the drop down menu underneath "ONS Record Type", and choose how long you would like to register your Lokinet name for.
Add your preferred human readable name, and your existing .loki address, an Oxen address may also be specified if you want to delegate ownership to a wallet separate from the wallet currently in use. Backup owners can be specified and have the same rights as the owner.
Once the relevant fields have been populated press "purchase" and confirm the transaction, transactions can take up to 20 minutes to confirm, once confirmed, you record will be registered and resolution between the human readable name and the default loki address should be complete.