@@ -17,6 +17,7 @@ public class IPFS {
1717
1818 public static final Version MIN_VERSION = Version .parse ("0.4.11" );
1919 public enum PinType {all , direct , indirect , recursive }
20+ public enum PinStatus {queued , pinning , pinned , failed }
2021 public List <String > ObjectTemplates = Arrays .asList ("unixfs-dir" );
2122 public List <String > ObjectPatchTypes = Arrays .asList ("add-link" , "rm-link" , "set-data" , "append-data" );
2223 private static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 10_000 ;
@@ -25,7 +26,7 @@ public enum PinType {all, direct, indirect, recursive}
2526 public final String host ;
2627 public final int port ;
2728 public final String protocol ;
28- private final String version ;
29+ private final String apiVersion ;
2930 private final int connectTimeoutMillis ;
3031 private final int readTimeoutMillis ;
3132 public final Key key = new Key ();
@@ -36,6 +37,7 @@ public enum PinType {all, direct, indirect, recursive}
3637 public final IPFSObject object = new IPFSObject ();
3738 public final Swarm swarm = new Swarm ();
3839 public final Bootstrap bootstrap = new Bootstrap ();
40+ public final Bitswap bitswap = new Bitswap ();
3941 public final Block block = new Block ();
4042 public final CidAPI cid = new CidAPI ();
4143 public final Dag dag = new Dag ();
@@ -50,6 +52,7 @@ public enum PinType {all, direct, indirect, recursive}
5052 public final Stats stats = new Stats ();
5153 public final Name name = new Name ();
5254 public final Pubsub pubsub = new Pubsub ();
55+ public final VersionAPI version = new VersionAPI ();
5356
5457 public IPFS (String host , int port ) {
5558 this (host , port , "/api/v0/" , false );
@@ -81,7 +84,7 @@ public IPFS(String host, int port, String version, int connectTimeoutMillis, int
8184 this .protocol = "http" ;
8285 }
8386
84- this .version = version ;
87+ this .apiVersion = version ;
8588 // Check IPFS is sufficiently recent
8689 try {
8790 Version detected = Version .parse (version ());
@@ -98,7 +101,7 @@ public IPFS(String host, int port, String version, int connectTimeoutMillis, int
98101 * @return current IPFS object with configured timeout
99102 */
100103 public IPFS timeout (int timeout ) {
101- return new IPFS (host , port , version , timeout , timeout , protocol .equals ("https" ));
104+ return new IPFS (host , port , apiVersion , timeout , timeout , protocol .equals ("https" ));
102105 }
103106
104107 public String shutdown () throws IOException {
@@ -118,7 +121,7 @@ public List<MerkleNode> add(NamedStreamable file, boolean wrap, boolean hashOnly
118121 }
119122
120123 public List <MerkleNode > add (List <NamedStreamable > files , boolean wrap , boolean hashOnly ) throws IOException {
121- Multipart m = new Multipart (protocol + "://" + host + ":" + port + version + "add?stream-channels=true&w=" +wrap + "&n=" +hashOnly , "UTF-8" );
124+ Multipart m = new Multipart (protocol + "://" + host + ":" + port + apiVersion + "add?stream-channels=true&w=" +wrap + "&n=" +hashOnly , "UTF-8" );
122125 for (NamedStreamable file : files ) {
123126 if (file .isDirectory ()) {
124127 m .addSubtree (Paths .get ("" ), file );
@@ -204,7 +207,10 @@ public List<Multihash> add(Multihash hash) throws IOException {
204207 .map (x -> Cid .decode ((String ) x ))
205208 .collect (Collectors .toList ());
206209 }
207-
210+ public Map addRemote (String service , Multihash hash , Optional <String > name , boolean background ) throws IOException {
211+ String nameArg = name .isPresent () ? "&name=" + name .get () : "" ;
212+ return retrieveMap ("pin/remote/add?arg=" + hash + "&service=" + service + nameArg + "&background=" + background );
213+ }
208214 public Map <Multihash , Object > ls () throws IOException {
209215 return ls (PinType .direct );
210216 }
@@ -215,6 +221,13 @@ public Map<Multihash, Object> ls(PinType type) throws IOException {
215221 .collect (Collectors .toMap (x -> Cid .decode (x .getKey ()), x -> x .getValue ()));
216222 }
217223
224+ public Map lsRemote (String service , Optional <String > name , Optional <List <PinStatus >> statusList ) throws IOException {
225+ String nameArg = name .isPresent () ? "&name=" + name .get () : "" ;
226+ String statusArg = statusList .isPresent () ? statusList .get ().stream ().
227+ map (p -> "&status=" + p ).collect (Collectors .joining ()) : "" ;
228+ return retrieveMap ("pin/remote/ls?service=" + service + nameArg + statusArg );
229+ }
230+
218231 public List <Multihash > rm (Multihash hash ) throws IOException {
219232 return rm (hash , true );
220233 }
@@ -224,12 +237,36 @@ public List<Multihash> rm(Multihash hash, boolean recursive) throws IOException
224237 return ((List <Object >) json .get ("Pins" )).stream ().map (x -> Cid .decode ((String ) x )).collect (Collectors .toList ());
225238 }
226239
240+ public String rmRemote (String service , Optional <String > name , Optional <List <PinStatus >> statusList , Optional <List <Multihash >> cidList ) throws IOException {
241+ String nameArg = name .isPresent () ? "&name=" + name .get () : "" ;
242+ String statusArg = statusList .isPresent () ? statusList .get ().stream ().
243+ map (p -> "&status=" + p ).collect (Collectors .joining ()) : "" ;
244+ String cidArg = cidList .isPresent () ? cidList .get ().stream ().
245+ map (p -> "&cid=" + p .toBase58 ()).collect (Collectors .joining ()) : "" ;
246+ return retrieveString ("pin/remote/rm?service=" + service + nameArg + statusArg + cidArg );
247+ }
248+
249+ public String addRemoteService (String service , String endPoint , String key ) throws IOException {
250+ return retrieveString ("pin/remote/service/add?arg=" + service + "&arg=" + endPoint + "&arg=" + key );
251+ }
252+
253+ public Map lsRemoteService (boolean stat ) throws IOException {
254+ return retrieveMap ("pin/remote/service/ls?stat=" + stat );
255+ }
256+
257+ public String rmRemoteService (String service ) throws IOException {
258+ return retrieveString ("pin/remote/service/rm?arg=" + service );
259+ }
260+
227261 public List <Multihash > update (Multihash existing , Multihash modified , boolean unpin ) throws IOException {
228262 return ((List <Object >)((Map )retrieveAndParse ("pin/update?stream-channels=true&arg=" + existing + "&arg=" + modified + "&unpin=" + unpin )).get ("Pins" ))
229263 .stream ()
230264 .map (x -> Cid .decode ((String ) x ))
231265 .collect (Collectors .toList ());
232266 }
267+ public Map verify (boolean verbose , boolean quite ) throws IOException {
268+ return retrieveMap ("pin/verify?verbose=" + verbose + "&quite=" + quite );
269+ }
233270 }
234271
235272 /* 'ipfs key' is a command for dealing with IPNS keys.
@@ -269,7 +306,7 @@ public Map ls() throws IOException {
269306
270307 public class MultibaseAPI {
271308 public String decode (NamedStreamable encoded_file ) {
272- Multipart m = new Multipart (protocol + "://" + host + ":" + port + version +
309+ Multipart m = new Multipart (protocol + "://" + host + ":" + port + apiVersion +
273310 "multibase/decode" , "UTF-8" );
274311 try {
275312 if (encoded_file .isDirectory ()) {
@@ -284,7 +321,7 @@ public String decode(NamedStreamable encoded_file) {
284321 }
285322 public String encode (Optional <String > encoding , NamedStreamable file ) {
286323 String b = encoding .map (f -> "?b=" + f ).orElse ("?b=base64url" );
287- Multipart m = new Multipart (protocol + "://" + host + ":" + port + version +
324+ Multipart m = new Multipart (protocol + "://" + host + ":" + port + apiVersion +
288325 "multibase/encode" + b , "UTF-8" );
289326 try {
290327 if (file .isDirectory ()) {
@@ -302,7 +339,7 @@ public List<Map> list(boolean prefix, boolean numeric) throws IOException {
302339 }
303340 public String transcode (Optional <String > encoding , NamedStreamable file ) {
304341 String b = encoding .map (f -> "?b=" + f ).orElse ("?b=base64url" );
305- Multipart m = new Multipart (protocol + "://" + host + ":" + port + version +
342+ Multipart m = new Multipart (protocol + "://" + host + ":" + port + apiVersion +
306343 "multibase/transcode" + b , "UTF-8" );
307344 try {
308345 if (file .isDirectory ()) {
@@ -341,6 +378,13 @@ public Map version() throws IOException {
341378 }
342379 }
343380
381+
382+ public class VersionAPI {
383+ public Map versionDeps () throws IOException {
384+ return retrieveMap ("version/deps" );
385+ }
386+ }
387+
344388 public class Pubsub {
345389 public Object ls () throws IOException {
346390 return retrieveAndParse ("pubsub/ls" );
@@ -363,7 +407,7 @@ public Object peers(String topic) throws IOException {
363407 */
364408 public void pub (String topic , String data ) {
365409 String encodedTopic = Multibase .encode (Multibase .Base .Base64Url , topic .getBytes ());
366- Multipart m = new Multipart (protocol +"://" + host + ":" + port + version +"pubsub/pub?arg=" + encodedTopic , "UTF-8" );
410+ Multipart m = new Multipart (protocol +"://" + host + ":" + port + apiVersion +"pubsub/pub?arg=" + encodedTopic , "UTF-8" );
367411 try {
368412 m .addFilePart ("file" , Paths .get ("" ), new NamedStreamable .ByteArrayWrapper (data .getBytes ()));
369413 String res = m .finish ();
@@ -445,7 +489,7 @@ public List<MerkleNode> put(List<byte[]> data, Optional<String> format) throws I
445489
446490 public MerkleNode put (byte [] data , Optional <String > format ) throws IOException {
447491 String fmt = format .map (f -> "&format=" + f ).orElse ("" );
448- Multipart m = new Multipart (protocol +"://" + host + ":" + port + version +"block/put?stream-channels=true" + fmt , "UTF-8" );
492+ Multipart m = new Multipart (protocol +"://" + host + ":" + port + apiVersion +"block/put?stream-channels=true" + fmt , "UTF-8" );
449493 try {
450494 m .addFilePart ("file" , Paths .get ("" ), new NamedStreamable .ByteArrayWrapper (data ));
451495 String res = m .finish ();
@@ -465,7 +509,7 @@ public Map stat(Multihash hash) throws IOException {
465509 public class IPFSObject {
466510 @ Deprecated
467511 public List <MerkleNode > put (List <byte []> data ) throws IOException {
468- Multipart m = new Multipart (protocol +"://" + host + ":" + port + version +"object/put?stream-channels=true" , "UTF-8" );
512+ Multipart m = new Multipart (protocol +"://" + host + ":" + port + apiVersion +"object/put?stream-channels=true" , "UTF-8" );
469513 for (byte [] f : data )
470514 m .addFilePart ("file" , Paths .get ("" ), new NamedStreamable .ByteArrayWrapper (f ));
471515 String res = m .finish ();
@@ -475,7 +519,7 @@ public List<MerkleNode> put(List<byte[]> data) throws IOException {
475519 public List <MerkleNode > put (String encoding , List <byte []> data ) throws IOException {
476520 if (!"json" .equals (encoding ) && !"protobuf" .equals (encoding ))
477521 throw new IllegalArgumentException ("Encoding must be json or protobuf" );
478- Multipart m = new Multipart (protocol +"://" + host + ":" + port + version +"object/put?stream-channels=true&encoding=" +encoding , "UTF-8" );
522+ Multipart m = new Multipart (protocol +"://" + host + ":" + port + apiVersion +"object/put?stream-channels=true&encoding=" +encoding , "UTF-8" );
479523 for (byte [] f : data )
480524 m .addFilePart ("file" , Paths .get ("" ), new NamedStreamable .ByteArrayWrapper (f ));
481525 String res = m .finish ();
@@ -529,7 +573,7 @@ public MerkleNode patch(Multihash base, String command, Optional<byte[]> data, O
529573 case "append-data" :
530574 if (!data .isPresent ())
531575 throw new IllegalStateException ("set-data requires data!" );
532- Multipart m = new Multipart (protocol +"://" + host + ":" + port + version +"object/patch/" +command +"?arg=" +base .toBase58 ()+"&stream-channels=true" , "UTF-8" );
576+ Multipart m = new Multipart (protocol +"://" + host + ":" + port + apiVersion +"object/patch/" +command +"?arg=" +base .toBase58 ()+"&stream-channels=true" , "UTF-8" );
533577 m .addFilePart ("file" , Paths .get ("" ), new NamedStreamable .ByteArrayWrapper (data .get ()));
534578 String res = m .finish ();
535579 return MerkleNode .fromJSON (JSONParser .parse (res ));
@@ -665,7 +709,7 @@ public Map stat(String path) throws IOException {
665709 public String write (String path , NamedStreamable uploadFile , boolean create , boolean parents ) throws IOException {
666710 String arg = URLEncoder .encode (path , "UTF-8" );
667711 String rpcParams = "files/write?arg=" + arg + "&create=" + create + "&parents=" + parents ;
668- URL target = new URL (protocol ,host ,port ,version + rpcParams );
712+ URL target = new URL (protocol ,host ,port ,apiVersion + rpcParams );
669713 Multipart m = new Multipart (target .toString (),"UTF-8" );
670714 if (uploadFile .isDirectory ()) {
671715 throw new IllegalArgumentException ("Input must be a file" );
@@ -704,6 +748,21 @@ public List<MultiAddress> bootstrap() throws IOException {
704748 }).collect (Collectors .toList ());
705749 }
706750
751+ public class Bitswap {
752+ public Map ledger (Multihash peerId ) throws IOException {
753+ return retrieveMap ("bitswap/ledger?arg=" +peerId );
754+ }
755+
756+ public String reprovide () throws IOException {
757+ return retrieveString ("bitswap/reprovide" );
758+ }
759+ public Map stat () throws IOException {
760+ return retrieveMap ("bitswap/stat" );
761+ }
762+ public Map wantlist (Multihash peerId ) throws IOException {
763+ return retrieveMap ("bitswap/wantlist?peer=" + peerId );
764+ }
765+ }
707766 public class Bootstrap {
708767
709768 public List <MultiAddress > add (MultiAddress addr ) throws IOException {
@@ -762,7 +821,12 @@ public Map<Multihash, List<MultiAddress>> addrs() throws IOException {
762821 .map (MultiAddress ::new )
763822 .collect (Collectors .toList ())));
764823 }
765-
824+ public Map listenAddrs () throws IOException {
825+ return retrieveMap ("swarm/addrs/listen" );
826+ }
827+ public Map localAddrs (boolean showPeerId ) throws IOException {
828+ return retrieveMap ("swarm/addrs/local?id=" + showPeerId );
829+ }
766830 public Map connect (MultiAddress multiAddr ) throws IOException {
767831 Map m = retrieveMap ("swarm/connect?arg=" +multiAddr );
768832 return m ;
@@ -772,6 +836,24 @@ public Map disconnect(MultiAddress multiAddr) throws IOException {
772836 Map m = retrieveMap ("swarm/disconnect?arg=" +multiAddr );
773837 return m ;
774838 }
839+ public Map filters () throws IOException {
840+ return retrieveMap ("swarm/filters" );
841+ }
842+ public Map filtersAdd (String multiAddrFilter ) throws IOException {
843+ return retrieveMap ("swarm/filters/add?arg=" +multiAddrFilter );
844+ }
845+ public Map filtersRm (String multiAddrFilter ) throws IOException {
846+ return retrieveMap ("swarm/filters/rm?arg=" +multiAddrFilter );
847+ }
848+ public Map peeringLs () throws IOException {
849+ return retrieveMap ("swarm/peering/ls" );
850+ }
851+ public Map peeringAdd (MultiAddress multiAddr ) throws IOException {
852+ return retrieveMap ("swarm/peering/add?arg=" +multiAddr );
853+ }
854+ public Map peeringRm (Multihash multiAddr ) throws IOException {
855+ return retrieveMap ("swarm/peering/rm?arg=" +multiAddr );
856+ }
775857 }
776858
777859 public class Dag {
@@ -792,7 +874,7 @@ public MerkleNode put(byte[] object, String outputFormat) throws IOException {
792874 }
793875
794876 public MerkleNode put (String inputFormat , byte [] object , String outputFormat ) throws IOException {
795- String prefix = protocol + "://" + host + ":" + port + version ;
877+ String prefix = protocol + "://" + host + ":" + port + apiVersion ;
796878 Multipart m = new Multipart (prefix + "dag/put/?stream-channels=true&input-codec=" + inputFormat + "&store-codec=" + outputFormat , "UTF-8" );
797879 m .addFilePart ("file" , Paths .get ("" ), new NamedStreamable .ByteArrayWrapper (object ));
798880 String res = m .finish ();
@@ -821,6 +903,10 @@ public String clearCmds() throws IOException {
821903 return retrieveString ("diag/cmds/clear" );
822904 }
823905
906+ public String profile () throws IOException {
907+ return retrieveString ("diag/profile" );
908+ }
909+
824910 public Map sys () throws IOException {
825911 return retrieveMap ("diag/sys?stream-channels=true" );
826912 }
@@ -886,7 +972,7 @@ public Map profileApply(String profile, boolean dryRun) throws IOException {
886972 }
887973
888974 public void replace (NamedStreamable file ) throws IOException {
889- Multipart m = new Multipart (protocol +"://" + host + ":" + port + version +"config/replace?stream-channels=true" , "UTF-8" );
975+ Multipart m = new Multipart (protocol +"://" + host + ":" + port + apiVersion +"config/replace?stream-channels=true" , "UTF-8" );
890976 m .addFilePart ("file" , Paths .get ("" ), file );
891977 String res = m .finish ();
892978 }
@@ -957,12 +1043,12 @@ private void retrieveAndParseStream(String path, Consumer<Object> results, Consu
9571043 }
9581044
9591045 private String retrieveString (String path ) throws IOException {
960- URL target = new URL (protocol , host , port , version + path );
1046+ URL target = new URL (protocol , host , port , apiVersion + path );
9611047 return new String (IPFS .get (target , connectTimeoutMillis , readTimeoutMillis ));
9621048 }
9631049
9641050 private byte [] retrieve (String path ) throws IOException {
965- URL target = new URL (protocol , host , port , version + path );
1051+ URL target = new URL (protocol , host , port , apiVersion + path );
9661052 return IPFS .get (target , connectTimeoutMillis , readTimeoutMillis );
9671053 }
9681054
@@ -1055,7 +1141,7 @@ private List<Object> getAndParseStream(String path) throws IOException {
10551141 }
10561142
10571143 private InputStream retrieveStream (String path ) throws IOException {
1058- URL target = new URL (protocol , host , port , version + path );
1144+ URL target = new URL (protocol , host , port , apiVersion + path );
10591145 return IPFS .getStream (target , connectTimeoutMillis , readTimeoutMillis );
10601146 }
10611147
@@ -1069,7 +1155,7 @@ private static InputStream getStream(URL target, int connectTimeoutMillis, int r
10691155 }
10701156
10711157 private Map postMap (String path , byte [] body , Map <String , String > headers ) throws IOException {
1072- URL target = new URL (protocol , host , port , version + path );
1158+ URL target = new URL (protocol , host , port , apiVersion + path );
10731159 return (Map ) JSONParser .parse (new String (post (target , body , headers , connectTimeoutMillis , readTimeoutMillis )));
10741160 }
10751161
0 commit comments