ecash-agora 0.1.1-rc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +8 -0
- package/.nycrc +4 -0
- package/README.md +122 -0
- package/agora.py +771 -0
- package/dist/ad.d.ts +15 -0
- package/dist/ad.d.ts.map +1 -0
- package/dist/ad.js +111 -0
- package/dist/ad.js.map +1 -0
- package/dist/agora.d.ts +178 -0
- package/dist/agora.d.ts.map +1 -0
- package/dist/agora.js +432 -0
- package/dist/agora.js.map +1 -0
- package/dist/consts.d.ts +5 -0
- package/dist/consts.d.ts.map +1 -0
- package/dist/consts.js +9 -0
- package/dist/consts.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/oneshot.d.ts +34 -0
- package/dist/oneshot.d.ts.map +1 -0
- package/dist/oneshot.js +204 -0
- package/dist/oneshot.js.map +1 -0
- package/dist/partial.d.ts +256 -0
- package/dist/partial.d.ts.map +1 -0
- package/dist/partial.js +955 -0
- package/dist/partial.js.map +1 -0
- package/eslint.config.js +16 -0
- package/package.json +52 -0
- package/tests/oneshot.test.ts +569 -0
- package/tests/partial-helper-alp.ts +131 -0
- package/tests/partial-helper-slp.ts +154 -0
- package/tests/partial.alp.bigsats.test.ts +694 -0
- package/tests/partial.alp.test.ts +586 -0
- package/tests/partial.slp.bigsats.test.ts +681 -0
- package/tests/partial.slp.test.ts +630 -0
- package/tsconfig.build.json +13 -0
- package/tsconfig.json +19 -0
package/.eslintignore
ADDED
package/.nycrc
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# ecash-agora: Non-interactive XEC -> token swaps using Script
|
|
2
|
+
|
|
3
|
+
## What's an "Agora"?
|
|
4
|
+
|
|
5
|
+
The agora (ἀγορά) was a central public space in ancient Greek city-states, and means "market" in modern Greek. The eCash Agora is similar in that sense, it's a protocol on eCash that allows anyone to offer their tokens in exchange for XEC.
|
|
6
|
+
|
|
7
|
+
## Is Agora a DEX?
|
|
8
|
+
|
|
9
|
+
Agora is a NEX, a "non-custodial exchange"; in contrast to e.g. Uniswap or other DEXes that are common on ETH, Agora doesn't pool any funds, but everyone offering tokens has them in their own independently controlled UTXOs.
|
|
10
|
+
|
|
11
|
+
You don't send your tokens to a central smart contract, you keep them in your wallet but expose them for others to take if they meet certain criteria.
|
|
12
|
+
|
|
13
|
+
In that sense, "exchange" might even be a misnomer, as there's no special server or platform required, it's using the P2P network directly, and trades are accepted on and broadcast from the user's own wallets.
|
|
14
|
+
|
|
15
|
+
## How can it be used?
|
|
16
|
+
|
|
17
|
+
eCash Agora allows users to lock their SLP/ALP tokens in a special UTXO, which behaves similar to to a "virtual vending machine", where other's can "insert" XEC and get tokens out.
|
|
18
|
+
|
|
19
|
+
For example, Alice can lock 1000 GRUMPY into an output with a Agora P2SH Script, and in the rules of the Script it requires others to send 20000 XEC to an output with an address controlled by Alice.
|
|
20
|
+
|
|
21
|
+
So, if Bob has 20000 XEC, he can send the 1000 GRUMPY to his own address by spending Alice's output with a transaction that sends the 20000 XEC to Alice. And the Agora Script enforces that this is handled correctly.
|
|
22
|
+
|
|
23
|
+
## Why does it work?
|
|
24
|
+
|
|
25
|
+
We can use Bitcoin's Script language to put spending conditions on a UTXO, for example a normal P2PKH requires us to provide a matching public key + signature, like this:
|
|
26
|
+
|
|
27
|
+
`OP_DUP OP_HASH160 <public key hash> OP_EQUALVERIFY OP_CHECKSIG`
|
|
28
|
+
|
|
29
|
+
These Scripts are little programs that a spender has to make happy (i.e. make them result in producing a "true" result) in order to spend them.
|
|
30
|
+
|
|
31
|
+
eCash has the ability to put conditions on a transaction spending a UTXO for a while already, you can read about them [here](https://read.cash/@pein/bch-covenants-with-spedn-4a980ed3).
|
|
32
|
+
|
|
33
|
+
**We can use this to constrain that an output can only be spent if it sends some XEC to a specific address, which is essentially all that Agora does**
|
|
34
|
+
|
|
35
|
+
At the end, it's an `OP_EQUALVERIFY` operation that will fail if someone tries to get the tokens without sending the required tokens to the required address.
|
|
36
|
+
|
|
37
|
+
## How does it work?
|
|
38
|
+
|
|
39
|
+
### Transaction
|
|
40
|
+
|
|
41
|
+
A transaction will look roughly like this, if Bob accepts all available tokens:
|
|
42
|
+
| Inputs | Outputs |
|
|
43
|
+
|--------|---------|
|
|
44
|
+
| Value: dust<br> Token: 1000 GRUMPY<br> Script: Alice's Agora P2SH | Value: 0<br> Script: SLP OP_RETURN |
|
|
45
|
+
| Value: 20000 XEC + fee<br> Script: Bob's P2PKH Script | Value: 20000 XEC<br> Script: Alice's P2PKH Script |
|
|
46
|
+
| | Value: dust<br> Token: 1000 GRUMPY<br> Script: Bob's P2PKH Script |
|
|
47
|
+
|
|
48
|
+
You can see that after the transaction, Alice has 20000 XEC and Bob has 1000 Grumpy.
|
|
49
|
+
|
|
50
|
+
The Agora P2SH script will ensure that the transaction has the shape as described above.
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
You can create a "one shot" offer (one that offers all or nothing) using `AgoraOneshot`, here to sell an SLP NFT:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
const enforcedOutputs: TxOutput[] = [
|
|
58
|
+
{ value: 0, script: slpSend(tokenId, SLP_NFT1_CHILD, [0, 1]) },
|
|
59
|
+
{ value: 80000, script: sellerP2pkh },
|
|
60
|
+
];
|
|
61
|
+
const agoraOneshot = new AgoraOneshot({
|
|
62
|
+
enforcedOutputs,
|
|
63
|
+
cancelPk: sellerPk,
|
|
64
|
+
});
|
|
65
|
+
const agoraScript = agoraOneshot.script();
|
|
66
|
+
const agoraP2sh = Script.p2sh(shaRmd160(agoraScript.bytecode));
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
A buyer can then accept this using `AgoraOneshotSignatory`:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
const txBuilder = new TxBuilder({
|
|
73
|
+
version: 2,
|
|
74
|
+
inputs: [
|
|
75
|
+
{
|
|
76
|
+
input: {
|
|
77
|
+
prevOut: {
|
|
78
|
+
txid: offerTxid,
|
|
79
|
+
outIdx: 1,
|
|
80
|
+
},
|
|
81
|
+
signData: {
|
|
82
|
+
value: 546,
|
|
83
|
+
redeemScript: agoraScript,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
signatory: AgoraOneshotSignatory(
|
|
87
|
+
buyerSk,
|
|
88
|
+
buyerPk,
|
|
89
|
+
enforcedOutputs.length,
|
|
90
|
+
),
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
input: {
|
|
94
|
+
prevOut: {
|
|
95
|
+
txid: buyerSatsTxid,
|
|
96
|
+
outIdx: 0,
|
|
97
|
+
},
|
|
98
|
+
signData: {
|
|
99
|
+
value: 90000,
|
|
100
|
+
outputScript: buyerP2pkh,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
signatory: P2PKHSignatory(buyerSk, buyerPk, ALL_BIP143),
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
outputs: [
|
|
107
|
+
{
|
|
108
|
+
value: 0,
|
|
109
|
+
script: slpSend(tokenId, SLP_NFT1_CHILD, [0, 1]),
|
|
110
|
+
},
|
|
111
|
+
{ value: 80000, script: sellerP2pkh },
|
|
112
|
+
{ value: 546, script: buyerP2pkh },
|
|
113
|
+
],
|
|
114
|
+
});
|
|
115
|
+
const acceptTx = txBuilder.sign(ecc);
|
|
116
|
+
await chronik.broadcastTx(acceptTx.ser());
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Changelog
|
|
120
|
+
|
|
121
|
+
- 0.1.0 - MVP [D16087](https://reviews.bitcoinabc.org/D16087) [D16111](https://reviews.bitcoinabc.org/D16111)
|
|
122
|
+
- 0.1.1 - Upgrading dependencies [D16374](https://reviews.bitcoinabc.org/D16374)
|