-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(atomic-swap): add atomic swap guide #41
base: master
Are you sure you want to change the base?
Conversation
guides/0000-atomic-swap.md
Outdated
@@ -0,0 +1,97 @@ | |||
### What is atomic swap |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer the template format. It seems more intuitive and easier to follow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've change the format. What do you think?
guides/0000-atomic-swap.md
Outdated
@@ -0,0 +1,97 @@ | |||
### What is atomic swap | |||
|
|||
Atomic swap is a feature where two different users can exchange different tokens in the same transaction without any third party and any trust. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd add that an atomic swap consists of a single transaction that is either executed or not. Hence, the parties do not have to trust each other. If Alice receives Bob's token, then Bob will certainly receives Alice's token.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added this to the summary. What do you think?
guides/0000-atomic-swap.md
Outdated
|
||
![atomic swap wallets drawio](https://user-images.githubusercontent.com/3298774/145630746-ca4c0011-2e01-4574-8143-f3c64c214f4e.png) | ||
|
||
The first thing to do is to define how many tokens will be exchanged, i.e. user1 will send X token1 to user2 and user2 will send Y token2 to user1. The atomic swap will happen in some steps that will be done in both wallets, where the users will need to exchange some information after each step. Below there is an image with each step and the explanation of them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd emphasize that the steps are supposed to be executed one after the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not all of them, right? There are steps that can be done concurrently.
That's why I added this in the diagram and it's clear with the number which steps can be done concurrently and the ones that have dependencies.
guides/0000-atomic-swap.md
Outdated
|
||
![atomic swap wallets drawio](https://user-images.githubusercontent.com/3298774/145630746-ca4c0011-2e01-4574-8143-f3c64c214f4e.png) | ||
|
||
The first thing to do is to define how many tokens will be exchanged, i.e. user1 will send X token1 to user2 and user2 will send Y token2 to user1. The atomic swap will happen in some steps that will be done in both wallets, where the users will need to exchange some information after each step. Below there is an image with each step and the explanation of them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel we can add a sequence diagram to illustrate each step and the communication between independent wallets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the end of the guide level explanation there is a diagram. Do you prefer to have each step separated? I think I like more the explanation text, then the full diagram.
guides/0000-atomic-swap.md
Outdated
|
||
The first thing to do is to define how many tokens will be exchanged, i.e. user1 will send X token1 to user2 and user2 will send Y token2 to user1. The atomic swap will happen in some steps that will be done in both wallets, where the users will need to exchange some information after each step. Below there is an image with each step and the explanation of them. | ||
|
||
#### Step 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before explaining each step in details, I'd add a summary like this:
- Wallet 1 and Wallet 2 agrees to exchange 3 X and 1 Y.
- Wallet 2 sends its inputs and change outputs to wallet 2.
- Wallet 1 generate an unsigned tx with all inputs and outputs.
- Wallet 1 signs its inputs (in my example, TxA.inputs[0] only).
- Note that the tx is not ready to be pushed yet.
- Wallet 1 sends bytes(tx) to Wallet 2.
- Wallet 2 receives bytes(tx) , decodes it, and check whether the inputs and ouputs are correct.
- Wallet 2 signs its inputs.
- Now tx is ready to be pushed.
- Wallet 2 pushes the transaction.
- Wallet 1 receives the transactions and confirms the swap.
Maybe it should in a sequence diagram.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add an example as well.
For example, let TxA be a transaction. Let X and Y be two different tokens. Then,
TxA.inputs[0] = 10 X (wallet 1)
TxA.inputs[1] = 5 Y (wallet 2)
TxA.outputs[0] = 3 X (wallet 2)
TxA.outputs[1] = 7 X (wallet 1, change)
TxA.outputs[2] = 1 Y (wallet 1)
TxA.outputs[2] = 4Y (wallet 2, change)
In this case, TxA is an atomic swap of 3 X and 1 Y from wallet 1 and wallet 2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added the summary but I've changed a bit. The example I decided to use is with a central coordinator because it's the request we had from a use case.
About the example, I guess it's confusing this way, we already have the code example in the reference level, I guess it's enough. What do you think?
The guide level looks good to me, I would just suggest a refactor on the reference level: Reference-level explanation
> node
const hathorLib = require('@hathor/wallet-lib')
const conn1 = new hathorLib.Connection({network: 'mainnet', servers: ['https://node1.mainnet.hathor.network/v1a/']});
const conn2 = new hathorLib.Connection({network: 'mainnet', servers: ['https://node1.mainnet.hathor.network/v1a/']});
const pin = '123';
const password = '123';
const wallet1 = new hathorLib.HathorWallet({connection: conn1, password, pinCode: pin, seed: seed1});
const wallet2 = new hathorLib.HathorWallet({connection: conn2, password, pinCode: pin, seed: seed2});
// Start wallets
wallet1.start()
wallet2.start()
wallet1.isReady()
wallet2.isReady()
wallet1.getUtxos({ token: token1 })
wallet2.getUtxos({ token: token2 })
const tokens = [token1, token2]
// With the data from the get utxos method you will fill the inputs objects
// in the example below we will swap token1 from wallet1 with token2 from wallet2. token1 will be sent from a single utxo and token2 will be sent from 2 utxos.
const inputs = [{
tx_id: txId1,
index: index1,
token: token1,
address: address1,
}, {
tx_id: txId2,
index: index2,
token: token2,
address: address2,
}, {
tx_id: txId3,
index: index3,
token: token2,
address: address3,
}];
const outputs = [{
address: address4,
value: value1,
token: token1,
tokenData: 1,
}, {
address: address5,
value: value2,
token: token2,
tokenData: 2
}];
const data = {
tokens,
inputs,
outputs,
};
hathorLib.transaction.completeTx(data);
const dataToSign = hathorLib.transaction.dataToSign(data);
hathorLib.storage.setStore(wallet1.store);
hathorLib.transaction.signTx(data, dataToSign, pin);
hathorLib.storage.setStore(wallet2.store);
hathorLib.transaction.signTx(data, dataToSign, pin);
const transaction = hathorLib.helpersUtils.createTxFromData(data, new hathorLib.Network('mainnet'));
transaction.prepareToSend()
const sendTxObj = new hathorLib.SendTransaction({ transaction })
await sendTxObj.runFromMining(); |
Refactor done. It's much better. Can you take a look again please? |
Rendered