Skip to content

Commit b0cc132

Browse files
committed
Pin File To IPFS barley working; multi-part upload is a bit clunky with ContentDispositionHeaderValue.
1 parent a0fbdfa commit b0cc132

3 files changed

Lines changed: 83 additions & 2 deletions

File tree

Source/Pinata.Client.Tests/IntegrationTests/AllTests.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using System.Threading.Tasks;
1+
using System.Net.Http;
2+
using System.Net.Http.Headers;
3+
using System.Net.Mime;
4+
using System.Text;
5+
using System.Threading.Tasks;
26
using FluentAssertions;
37
using Newtonsoft.Json;
48
using NUnit.Framework;
@@ -111,5 +115,32 @@ public async Task pinning_set_userPinPolicy()
111115
policy.AddOrUpdateRegion("FRA1", 1);
112116
var r = await this.client.Pinning.UserPinPolicyAsync(policy);
113117
}
118+
119+
[Test]
120+
public async Task pinning_pinFileToIPFS_bytes()
121+
{
122+
var html = @"
123+
<html>
124+
<head>
125+
<title>Hello IPFS!</title>
126+
</head>
127+
<body>
128+
<h1>Hello World</h1>
129+
</body>
130+
</html>
131+
";
132+
var r = await this.client.Pinning.PinFileToIPFSAsync(content =>
133+
{
134+
var fileData = new StringContent(html, Encoding.UTF8, MediaTypeNames.Text.Html);
135+
var header = new ContentDispositionHeaderValue("form-data") {
136+
Name = "file",
137+
FileName = "test.html"
138+
};
139+
fileData.Headers.ContentDisposition = header;
140+
141+
content.Add(fileData);
142+
});
143+
144+
}
114145
}
115146
}

Source/Pinata.Client.Tests/PinningTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,5 +136,19 @@ public async Task new_user_pin_policy()
136136

137137
await Verify(r);
138138
}
139+
140+
[Test]
141+
public async Task upload()
142+
{
143+
var svg = @"
144+
<svg xmlns=""http://www.w3.org/2000/svg"" viewBox=""0 0 100 100"">
145+
<circle cx=""50"" cy=""50"" r=""48"" fill=""none"" stroke=""#000""/>
146+
<path d=""M50,2a48,48 0 1 1 0,96a24 24 0 1 1 0-48a24 24 0 1 0 0-48""/>
147+
<circle cx=""50"" cy=""26"" r=""6""/>
148+
<circle cx=""50"" cy=""74"" r=""6"" fill=""#FFF""/>
149+
</svg>";
150+
151+
152+
}
139153
}
140154
}

Source/Pinata.Client/PinataClient.Pinning.cs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.IO;
34
using System.Linq;
5+
using System.Net.Http;
46
using System.Text;
57
using System.Threading;
68
using System.Threading.Tasks;
79
using Flurl;
810
using Flurl.Http;
11+
using Flurl.Http.Configuration;
912
using Flurl.Http.Content;
1013
using Newtonsoft.Json;
1114
using Newtonsoft.Json.Linq;
@@ -27,6 +30,12 @@ public class PinataOptions : Json
2730
/// </summary>
2831
[JsonProperty("customPinPolicy")]
2932
public PinPolicy CustomPinPolicy { get; set; } = new PinPolicy();
33+
34+
/// <summary>
35+
/// Wrap your content inside of a directory when adding to IPFS. This allows users to retrieve content via a filename instead of just a hash.
36+
/// </summary>
37+
[JsonProperty("wrapWithDirectory")]
38+
public bool? WrapWithDirectory { get; set; }
3039
}
3140

3241
public class PinPolicy : Json
@@ -97,6 +106,11 @@ public interface IPinningEndpoint
97106
/// Following a successful call of this endpoint, the new pin policy provided will be utilized for every new piece of content pinned to IPFS via Pinata.
98107
/// </summary>
99108
Task<UserPinPolicyResponse> UserPinPolicyAsync(PinPolicy newPinPolicy, bool migratePreviousPins = false, CancellationToken cancellationToken = default);
109+
110+
/// <summary>
111+
/// This endpoint allows the sender to add and pin any file, or directory, to Pinata's IPFS nodes.
112+
/// </summary>
113+
Task<IFlurlResponse> PinFileToIPFSAsync(Action<CapturedMultipartContent> callback, PinataMetadata pinataMetadata = null, PinataOptions pinataOptions = null, CancellationToken cancellationToken = default);
100114
}
101115

102116
public partial class PinataClient : IPinningEndpoint
@@ -172,5 +186,27 @@ public Task<UserPinPolicyResponse> UserPinPolicyAsync(PinPolicy newPinPolicy, bo
172186
}, cancellationToken)
173187
.ReceiveJson<UserPinPolicyResponse>();
174188
}
189+
190+
public Task<IFlurlResponse> PinFileToIPFSAsync(Action<CapturedMultipartContent> callback, PinataMetadata pinataMetadata = null, PinataOptions pinataOptions = null, CancellationToken cancellationToken = default)
191+
{
192+
return this.PinningEndpoint
193+
.WithClient(this)
194+
.AppendPathSegment("pinFileToIPFS")
195+
.PostMultipartAsync(multiPart =>
196+
{
197+
callback(multiPart);
198+
if( pinataMetadata is not null )
199+
{
200+
multiPart.AddJson("pinataMetadata", pinataMetadata);
201+
}
202+
if( pinataOptions is not null )
203+
{
204+
multiPart.AddJson("pinataOptions", pinataOptions);
205+
}
206+
}, cancellationToken);
207+
}
175208
}
176209
}
210+
211+
212+

0 commit comments

Comments
 (0)