psffpp 1.0.1 → 1.1.0
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/LICENSE.md +1 -1
- package/README.md +34 -168
- package/index.js +170 -252
- package/package.json +8 -5
- package/test/mocks/wallet.js +161 -0
- package/test/mocks/write-price-mocks.js +302 -0
- package/test/unit/main-index-unit.js +84 -272
- package/.travis.yml +0 -33
- package/lib/nfts.js +0 -113
- package/lib/util.js +0 -50
- package/test/unit/nfts-unit.js +0 -190
- package/test/unit/util-unit.js +0 -91
- /package/test/{unit/mocks → mocks}/main-index-mocks.js +0 -0
- /package/test/{unit/mocks → mocks}/util-mocks.js +0 -0
package/LICENSE.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
|
-
Copyright (c)
|
|
2
|
+
Copyright (c) 2023 Chris Troutner <chris.troutner@gmail.com>
|
|
3
3
|
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
5
5
|
|
package/README.md
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
# psffpp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
PSFFPP = [Permissionless Software Foundation](https://psfoundation.info) [File Pinning Protocol](https://psffpp.com).
|
|
4
|
+
|
|
5
|
+
This is an npm library for node.js. It implements the [PS010 specification for the PSF File Pinning Protocol](https://github.com/Permissionless-Software-Foundation/specifications/blob/master/ps009-multisig-approval.md). The main consumers of this library is:
|
|
6
|
+
- [p2wdb-image-upload-backend](https://github.com/Permissionless-Software-Foundation/p2wdb-image-upload-backend) uses it generate Pin Claims for file uploads as demonstrated at [upload.psfoundation.info](https://upload.psfoundation.info).
|
|
7
|
+
- [ipfs-file-pin-service](https://github.com/Permissionless-Software-Foundation/ipfs-file-pin-service) uses it to verify Pin Claims before pinning the files.
|
|
8
|
+
- [psf-bch-wallet](https://github.com/Permissionless-Software-Foundation/psf-bch-wallet) is a command-line UI that uses this library to add files to the network.
|
|
4
9
|
|
|
5
10
|
## Instancing Library
|
|
6
|
-
This library depends on [minimal-slp-wallet](https://www.npmjs.com/package/minimal-slp-wallet). An instance of
|
|
11
|
+
This library depends on the [minimal-slp-wallet](https://www.npmjs.com/package/minimal-slp-wallet) and [psf-multisig-approval](https://www.npmjs.com/package/psf-multisig-approval) libraries. An instance of minimal-slp-wallet is expected to be injected into this library when it is instantiated. Here is an example:
|
|
7
12
|
|
|
8
13
|
```javascript
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
import SlpWallet from 'minimal-slp-wallet'
|
|
15
|
+
import PSFFPP from 'psffpp'
|
|
11
16
|
|
|
12
17
|
async function start() {
|
|
13
18
|
// Instance the BCH wallet
|
|
@@ -18,194 +23,55 @@ async function start() {
|
|
|
18
23
|
await wallet.initialize()
|
|
19
24
|
|
|
20
25
|
// Instance this library
|
|
21
|
-
const
|
|
26
|
+
const psffpp = new PSFFPP({wallet})
|
|
22
27
|
}
|
|
23
28
|
start()
|
|
24
29
|
```
|
|
25
30
|
|
|
26
|
-
## Get
|
|
27
|
-
PS009 uses NFTs as 'homing beacons'. It generates a multisignature wallet from the public keys of the NFT holders. Finding the addresses and public keys of the NFT holders is a foundational feature of the protocol. All NFTs are connected by the Group Token ID that generated them.
|
|
28
|
-
|
|
29
|
-
If the holder of the NFT has not made any transactions, then their public key will not be on the blockchain. In that case, the NFT and address will be added to the `keysNotFound` array. Those holders will not be included in the multisignature wallet.
|
|
30
|
-
|
|
31
|
-
```javascript
|
|
32
|
-
const groupTokenId = '8e8d90ebdb1791d58eba7acd428ff3b1e21c47fb7aba2ba3b5b815aa0fe7d6d5'
|
|
31
|
+
## Get the Write Price
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
console.log(result)
|
|
33
|
+
Retrieve the current cost-per-megabyte in PSF tokens, for writing data to the network.
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
{
|
|
39
|
-
keys: [
|
|
40
|
-
{
|
|
41
|
-
addr: 'bitcoincash:qz4zsa22glal5c4jqm748xge657gwuw2d5t9nvg64p',
|
|
42
|
-
pubKey: '021ca211a04a1d489ae77e01c28c97b02e733893890fda00a359ca8956c2e0d259',
|
|
43
|
-
nft: 'e86164aaa06efac1d6453951f67beafe042f0bceb9312845a95355b1e93aa846'
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
addr: 'bitcoincash:qpfvh07mdt7yq5czndaz5qq4g9q3m87qpspy7xaxgu',
|
|
47
|
-
pubKey: '0361fd21512b9072e8f6b984d9b04c57e5779867c2ad002999372268770fcb2674',
|
|
48
|
-
nft: 'da7ccbd5e24e468c9e7402489ca9148b5e76e588b73cc4aa4bbf1ca41d5808ab'
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
addr: 'bitcoincash:qpsxtzaa7rg677akcc2znpenpsy5jr2ygywmfd45p2',
|
|
52
|
-
pubKey: '03b9bdc40c478ab0536be29c368b26c48a5e8d6867fc34b77c727ab690365aae91',
|
|
53
|
-
nft: '0ec318bede8c2f229db840a24cb63d662ad91e8e6c840e46e6a8ff2d173049ce'
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
addr: 'bitcoincash:qqk3aczzggvxnfm7rwm0f9yz20yr00dmpv2f3tasdr',
|
|
57
|
-
pubKey: '033c930d4cff4ba68a70f7a21443e20ad4176173380d21f8c3ce27f7ce947f3246',
|
|
58
|
-
nft: '51624e772adafd7c6a9da38774e4f654282199bd5402e049ee087fc2bd900882'
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
addr: 'bitcoincash:qpszha37cjn6n83hpxn7zz5ndaa35vygtcgslxhpuc',
|
|
62
|
-
pubKey: '024be54accec310c2636140336ae548d610ba9b7ce300b3f42494b4a6f2963731f',
|
|
63
|
-
nft: 'e70cc72eeb15c82e96b1f8127d3b138b2fc8ea101fe9c62302ec641c05d4b97d'
|
|
64
|
-
}
|
|
65
|
-
],
|
|
66
|
-
keysNotFound: []
|
|
67
|
-
}
|
|
68
|
-
*/
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Get an Approval Transaction
|
|
72
|
-
This function will take a BCH address as input. It will search the transaction history for the address, and will return an object about the first `APPROVAL` transaction that it finds. If it can't find one, it will return null.
|
|
35
|
+
*Note: The minimum cost is 1MB, even if you upload a file smaller than that to the file pinning network.*
|
|
73
36
|
|
|
74
37
|
```javascript
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
const result = await ps009.getApprovalTx({address})
|
|
78
|
-
console.log(result)
|
|
38
|
+
const writePrice = await psffpp.getMcWritePrice()
|
|
39
|
+
console.log(writePrice)
|
|
79
40
|
|
|
80
41
|
/*
|
|
81
|
-
|
|
82
|
-
approvalTxid: 'a63f9fbcc901316e6e89f5a8caaad6b2ab268278b29866c6c22088bd3ab93900',
|
|
83
|
-
updateTxid: 'f8ea1fcd4481adfd62c6251c6a4f63f3d5ac3d5fdcc38b350d321d93254df65f',
|
|
84
|
-
approvalTxDetails: {
|
|
85
|
-
txid: 'a63f9fbcc901316e6e89f5a8caaad6b2ab268278b29866c6c22088bd3ab93900',
|
|
86
|
-
vin: [ [Object] ],
|
|
87
|
-
vout: [ [Object], [Object], [Object] ],
|
|
88
|
-
...
|
|
89
|
-
isValidSlp: false
|
|
90
|
-
},
|
|
91
|
-
opReturn: 'j\x07APPROVE@f8ea1fcd4481adfd62c6251c6a4f63f3d5ac3d5fdcc38b350d321d93254df65f'
|
|
92
|
-
}
|
|
42
|
+
0.08335233
|
|
93
43
|
*/
|
|
94
44
|
```
|
|
95
45
|
|
|
96
|
-
##
|
|
46
|
+
## Create a Pin Claim
|
|
97
47
|
|
|
98
|
-
|
|
48
|
+
Files are pinned in a two-step process:
|
|
49
|
+
1. Upload the file to the [IPFS](https://ipfs.io) network, which returns a [CID](https://docs.ipfs.tech/concepts/content-addressing/).
|
|
50
|
+
2. A Pin Claim is generated on the BCH blockchain using the IPFS CID.
|
|
99
51
|
|
|
100
|
-
|
|
101
|
-
|
|
52
|
+
Generating a Pin Claim is also a two-step process:
|
|
53
|
+
1. Calculate the cost of pinning the file (in PSF tokens), then burn that amount to generate a Proof-of-Burn (proof of payment). This is a transaction on the blockchain. and is returned as `pobTxid`.
|
|
54
|
+
2. Generate a Pin Claim transaction that includes the `pobTxid`, the CID, and the filename. This is a second transaction on the blockchain, and is returned as `claimTxid`.
|
|
102
55
|
|
|
103
|
-
|
|
104
|
-
console.log(result)
|
|
105
|
-
|
|
106
|
-
/*
|
|
107
|
-
{
|
|
108
|
-
cid: 'bafybeib5d6s6t3tq4lhwp2ocvz7y2ws4czgkrmhlhv5y5aeyh6bqrmsxxi',
|
|
109
|
-
ts: 1676560247168,
|
|
110
|
-
txid: 'f8ea1fcd4481adfd62c6251c6a4f63f3d5ac3d5fdcc38b350d321d93254df65f',
|
|
111
|
-
txDetails: {
|
|
112
|
-
txid: 'f8ea1fcd4481adfd62c6251c6a4f63f3d5ac3d5fdcc38b350d321d93254df65f',
|
|
113
|
-
hash: 'f8ea1fcd4481adfd62c6251c6a4f63f3d5ac3d5fdcc38b350d321d93254df65f',
|
|
114
|
-
vin: [ [Object] ],
|
|
115
|
-
vout: [ [Object], [Object], [Object], [Object] ],
|
|
116
|
-
...
|
|
117
|
-
isValidSlp: false
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
*/
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Get IPFS CID Data
|
|
125
|
-
|
|
126
|
-
The update transaction will reference an IPFS CID. That data will need to be retrieved from an IPFS gateway. The default gateway can be overwritten when this library is instantiated.
|
|
56
|
+
A Pin Claim can be generated with this library:
|
|
127
57
|
|
|
128
58
|
```javascript
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const cid = 'bafybeib5d6s6t3tq4lhwp2ocvz7y2ws4czgkrmhlhv5y5aeyh6bqrmsxxi'
|
|
59
|
+
const pinObj = {
|
|
60
|
+
cid: 'bafkreih7eeixbkyvabqdde4g5mdourjidxpsgf6bgz6f7ouxqr24stg6f4',
|
|
61
|
+
filename: 'test.txt',
|
|
62
|
+
fileSizeInMegabytes: 0.1
|
|
63
|
+
}
|
|
136
64
|
|
|
137
|
-
const
|
|
138
|
-
console.log(
|
|
65
|
+
const {pobTxid, claimTxid} = await psffpp.createPinClaim(pinObj)
|
|
66
|
+
console.log('pobTxid: ', pobTxid)
|
|
67
|
+
console.log('claimTxid: ', claimTxid)
|
|
139
68
|
|
|
140
69
|
/*
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
keys: [
|
|
144
|
-
{
|
|
145
|
-
addr: 'bitcoincash:qz4zsa22glal5c4jqm748xge657gwuw2d5t9nvg64p',
|
|
146
|
-
pubKey: '021ca211a04a1d489ae77e01c28c97b02e733893890fda00a359ca8956c2e0d259',
|
|
147
|
-
nft: 'e86164aaa06efac1d6453951f67beafe042f0bceb9312845a95355b1e93aa846'
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
addr: 'bitcoincash:qpfvh07mdt7yq5czndaz5qq4g9q3m87qpspy7xaxgu',
|
|
151
|
-
pubKey: '0361fd21512b9072e8f6b984d9b04c57e5779867c2ad002999372268770fcb2674',
|
|
152
|
-
nft: 'da7ccbd5e24e468c9e7402489ca9148b5e76e588b73cc4aa4bbf1ca41d5808ab'
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
addr: 'bitcoincash:qpsxtzaa7rg677akcc2znpenpsy5jr2ygywmfd45p2',
|
|
156
|
-
pubKey: '03b9bdc40c478ab0536be29c368b26c48a5e8d6867fc34b77c727ab690365aae91',
|
|
157
|
-
nft: '0ec318bede8c2f229db840a24cb63d662ad91e8e6c840e46e6a8ff2d173049ce'
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
addr: 'bitcoincash:qqk3aczzggvxnfm7rwm0f9yz20yr00dmpv2f3tasdr',
|
|
161
|
-
pubKey: '033c930d4cff4ba68a70f7a21443e20ad4176173380d21f8c3ce27f7ce947f3246',
|
|
162
|
-
nft: '51624e772adafd7c6a9da38774e4f654282199bd5402e049ee087fc2bd900882'
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
addr: 'bitcoincash:qpszha37cjn6n83hpxn7zz5ndaa35vygtcgslxhpuc',
|
|
166
|
-
pubKey: '024be54accec310c2636140336ae548d610ba9b7ce300b3f42494b4a6f2963731f',
|
|
167
|
-
nft: 'e70cc72eeb15c82e96b1f8127d3b138b2fc8ea101fe9c62302ec641c05d4b97d'
|
|
168
|
-
}
|
|
169
|
-
],
|
|
170
|
-
walletObj: {
|
|
171
|
-
address: 'bitcoincash:pqntzt6wcp38h8ud68wjnwh437uek76lhvhlwcm4fj',
|
|
172
|
-
scriptHex: 'a91426b12f4ec0627b9f8dd1dd29baf58fb99b7b5fbb87',
|
|
173
|
-
publicKeys: [
|
|
174
|
-
'021ca211a04a1d489ae77e01c28c97b02e733893890fda00a359ca8956c2e0d259',
|
|
175
|
-
'0361fd21512b9072e8f6b984d9b04c57e5779867c2ad002999372268770fcb2674',
|
|
176
|
-
'03b9bdc40c478ab0536be29c368b26c48a5e8d6867fc34b77c727ab690365aae91',
|
|
177
|
-
'033c930d4cff4ba68a70f7a21443e20ad4176173380d21f8c3ce27f7ce947f3246',
|
|
178
|
-
'024be54accec310c2636140336ae548d610ba9b7ce300b3f42494b4a6f2963731f'
|
|
179
|
-
],
|
|
180
|
-
requiredSigners: 3
|
|
181
|
-
},
|
|
182
|
-
multisigAddr: 'bitcoincash:pqntzt6wcp38h8ud68wjnwh437uek76lhvhlwcm4fj',
|
|
183
|
-
p2wdbWritePrice: 0.08335233
|
|
184
|
-
}
|
|
70
|
+
pobTxid: f1ff81aaac7f755875306e31c9137b2bb010587feffeb4c7d42b462ef08db0df
|
|
71
|
+
claimTxid: db338fdb7edc6ce6685c9897a9d9fd6f0e26d194bf12e1c87470b7dc2103a3e3
|
|
185
72
|
*/
|
|
186
73
|
```
|
|
187
74
|
|
|
188
|
-
## Validate an Approval Transaction
|
|
189
|
-
After data about the approval and update transactions have been retrieved, it's important to validate that the approval transaction is valid and has not been faked. This function will return either `true` or `false` depending on the result of testing the transaction validity.
|
|
190
|
-
|
|
191
|
-
```javascript
|
|
192
|
-
const address = 'bitcoincash:qrwe6kxhvu47ve6jvgrf2d93w0q38av7s5xm9xfehr'
|
|
193
|
-
const approvalObj = await ps009.getApprovalTx({ address })
|
|
194
|
-
|
|
195
|
-
const txid = 'f8ea1fcd4481adfd62c6251c6a4f63f3d5ac3d5fdcc38b350d321d93254df65f'
|
|
196
|
-
const updateObj = await ps009.getUpdateTx({ txid })
|
|
197
|
-
|
|
198
|
-
const cid = 'bafybeib5d6s6t3tq4lhwp2ocvz7y2ws4czgkrmhlhv5y5aeyh6bqrmsxxi'
|
|
199
|
-
const updateData = await ps009.getCidData({ cid })
|
|
200
|
-
|
|
201
|
-
const inObj = { approvalObj, updateObj, updateData }
|
|
202
|
-
const result = await ps009.validateApproval(inObj)
|
|
203
|
-
console.log(result)
|
|
204
|
-
|
|
205
|
-
/*
|
|
206
|
-
true
|
|
207
|
-
*/
|
|
208
|
-
```
|
|
209
75
|
|
|
210
76
|
# License
|
|
211
77
|
[MIT](LICENSE.md)
|