Skip to content

Commit 9a28208

Browse files
authored
Upgrade Synapse SDK and update uploader (#8)
* chore: upgrade synapse sdk and update uploader * Use constants for Pandora setup * Improve uploader with allowance checks * Update dev script and tests * Handle allowances after preflight
1 parent 64cae3f commit 9a28208

File tree

7 files changed

+106
-44
lines changed

7 files changed

+106
-44
lines changed

components/FileUploader.tsx

Lines changed: 65 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { ethers } from "ethers";
33
import { useState, useCallback } from "react";
44
import { useAccount } from "wagmi";
55

6-
import { Synapse } from "@filoz/synapse-sdk";
7-
import { calculate as calculateCommP } from "@filoz/synapse-sdk/commp";
6+
import { Synapse, CONTRACT_ADDRESSES, TOKENS } from "@filoz/synapse-sdk";
7+
import { PandoraService } from "@filoz/synapse-sdk/pandora";
88

99
export function FileUploader() {
1010
const [file, setFile] = useState<File | null>(null);
@@ -17,7 +17,7 @@ export function FileUploader() {
1717
fileName: string;
1818
fileSize: number;
1919
commp: string;
20-
txHash: string;
20+
rootId?: number;
2121
} | null>(null);
2222

2323
const handleDrag = useCallback((e: React.DragEvent) => {
@@ -62,44 +62,75 @@ export function FileUploader() {
6262

6363
// 2) Initialize ethers provider & signer
6464
const provider = new ethers.BrowserProvider(window.ethereum);
65-
const signer = await provider.getSigner();
66-
// (Note: Synapse.create({ provider }) will pick up the signer automatically)
6765

6866
// 3) Create Synapse instance
69-
const synapse = await Synapse.create({ provider });
70-
const balance = await synapse.payments.walletBalance();
71-
console.log("FIL balance:", balance.toString());
67+
const pandoraAddress = CONTRACT_ADDRESSES.PANDORA_SERVICE.calibration;
68+
const synapse = await Synapse.create({
69+
provider,
70+
pandoraAddress,
71+
});
72+
const filBalance = await synapse.payments.walletBalance();
73+
const usdfcBalance = await synapse.payments.walletBalance(TOKENS.USDFC);
74+
console.log("FIL balance:", filBalance.toString());
75+
console.log("USDFC balance:", usdfcBalance.toString());
7276

73-
// 4) Create (mock) StorageService
74-
// Because the real StorageService is “pending,” this will return MockStorageService
77+
// 4) Create StorageService using Synapse SDK v0.5
78+
setStatus("Creating storage service...");
7579
const storage = await synapse.createStorage({
76-
storageProvider: "f01234", // replace with a valid provider ID or leave as mock
80+
withCDN: false,
81+
callbacks: {
82+
onProviderSelected: (provider) => {
83+
console.log("Selected storage provider:", provider.owner);
84+
console.log("PDP URL:", provider.pdpUrl);
85+
},
86+
onProofSetResolved: (info) => {
87+
if (info.isExisting) {
88+
console.log("Using existing proof set:", info.proofSetId);
89+
} else {
90+
console.log("Created new proof set:", info.proofSetId);
91+
}
92+
},
93+
onProofSetCreationStarted: (txHash) => {
94+
console.log("Creating proof set, tx:", txHash);
95+
},
96+
},
7797
});
7898

79-
// 5) Kick off upload (→ MockStorageService.upload under the hood)
80-
setStatus("Uploading to mock storage service...");
81-
const uploadTask = storage.upload(uint8ArrayBytes);
82-
83-
// 6) Wait for CommP calculation (mock)
84-
const commp = await uploadTask.commp();
85-
console.log("CommP (mock):", commp);
99+
// 5) Run a preflight check
100+
setStatus("Running preflight check...");
101+
const preflight = await storage.preflightUpload(uint8ArrayBytes.length);
86102

87-
// 7) (Optional) If you want to display intermediate progress, you could do that here.
88-
// But MockStorageService usually just resolves immediately.
89-
setProgress(50);
90-
setStatus("Finalizing upload...");
103+
if (!preflight.allowanceCheck.sufficient) {
104+
console.log("Insufficient allowances, preparing upload...");
105+
const pandoraService = new PandoraService(provider, pandoraAddress);
106+
const prep = await pandoraService.prepareStorageUpload(
107+
{ dataSize: uint8ArrayBytes.length },
108+
synapse.payments
109+
);
110+
for (const action of prep.actions) {
111+
setStatus(action.description + "...");
112+
await action.execute();
113+
}
114+
}
91115

92-
// 8) Wait for “chain commit” (mock)
93-
const txHash = await uploadTask.done();
94-
console.log("Mock txHash:", txHash);
116+
// 6) Upload the file using the new API
117+
setStatus("Uploading to storage provider...");
118+
const result = await storage.upload(uint8ArrayBytes, {
119+
onUploadComplete: (commp) => {
120+
console.log("CommP:", commp);
121+
},
122+
onRootAdded: () => {
123+
console.log("Root added to proof set");
124+
}
125+
});
95126

96127
setProgress(100);
97-
setStatus("✅ File uploaded successfully (mock)!");
128+
setStatus("✅ File uploaded successfully!");
98129
setUploadedInfo({
99130
fileName: file.name,
100131
fileSize: file.size,
101-
commp: commp.toLocaleString(),
102-
txHash: txHash,
132+
commp: result.commp,
133+
rootId: result.rootId,
103134
});
104135
} catch (err: any) {
105136
console.error(err);
@@ -122,7 +153,6 @@ export function FileUploader() {
122153
return null;
123154
}
124155

125-
console.log(uploadedInfo);
126156
return (
127157
<div className="w-full max-w-md">
128158
<div
@@ -232,10 +262,12 @@ export function FileUploader() {
232262
<span className="font-medium">CommP:</span>{" "}
233263
{uploadedInfo.commp}
234264
</div>
235-
<div className="break-all">
236-
<span className="font-medium">Tx Hash:</span>{" "}
237-
{uploadedInfo.txHash}
238-
</div>
265+
{uploadedInfo.rootId != null && (
266+
<div className="break-all">
267+
<span className="font-medium">Root ID:</span>{" "}
268+
{uploadedInfo.rootId}
269+
</div>
270+
)}
239271
</div>
240272
</div>
241273
)}

components/__tests__/FileUploader.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,7 @@ test('uploads file and shows success status', async () => {
3636
await waitFor(() => {
3737
expect(screen.getByText(/file uploaded successfully/i)).toBeInTheDocument();
3838
});
39+
await waitFor(() => {
40+
expect(screen.getByText(/root id/i)).toBeInTheDocument();
41+
});
3942
});

jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module.exports = {
99
moduleNameMapper: {
1010
'^@/(.*)$': '<rootDir>/$1',
1111
'^@filoz/synapse-sdk$': '<rootDir>/test/__mocks__/synapse-sdk.js',
12+
'^@filoz/synapse-sdk/pandora$': '<rootDir>/test/__mocks__/synapse-sdk.js',
1213
'\\.(css|less|scss|sass)$': 'identity-obj-proxy'
1314
},
1415
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts']

jest.setup.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
import '@testing-library/jest-dom';
2+
(global as any).__SYNAPSE_SDK_SKIP_DELAYS__ = true;

package-lock.json

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
"version": "0.1.0",
44
"private": true,
55
"scripts": {
6-
"dev": "next dev --turbopack",
6+
"dev": "next dev",
77
"build": "next build",
88
"start": "next start",
99
"lint": "next lint",
1010
"test": "jest"
1111
},
1212
"dependencies": {
13-
"@filoz/synapse-sdk": "^0.1.0",
13+
"@filoz/synapse-sdk": "^0.5.0",
1414
"@rainbow-me/rainbowkit": "^2.2.5",
1515
"ethers": "^6.14.3",
1616
"next": "15.3.2",

test/__mocks__/synapse-sdk.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,37 @@
11
module.exports = {
2+
TOKENS: {
3+
USDFC: 'USDFC',
4+
FIL: 'FIL',
5+
},
6+
CONTRACT_ADDRESSES: {
7+
PANDORA_SERVICE: {
8+
calibration: '0xMockPandoraAddress',
9+
},
10+
},
11+
PandoraService: class {
12+
constructor() {}
13+
prepareStorageUpload = jest.fn().mockResolvedValue({
14+
estimatedCost: { perEpoch: 0n, perDay: 0n, perMonth: 0n },
15+
allowanceCheck: { sufficient: true, message: '' },
16+
actions: [],
17+
});
18+
},
219
Synapse: {
320
create: jest.fn(async () => ({
421
payments: { walletBalance: jest.fn().mockResolvedValue(BigInt(0)) },
522
createStorage: jest.fn().mockResolvedValue({
6-
upload: jest.fn(() => ({
7-
commp: jest.fn().mockResolvedValue('mock-commp'),
8-
done: jest.fn().mockResolvedValue('0xmock')
9-
}))
10-
})
23+
preflightUpload: jest.fn().mockResolvedValue({
24+
estimatedCost: { perEpoch: 0n, perDay: 0n, perMonth: 0n },
25+
allowanceCheck: { sufficient: true, message: '' },
26+
selectedProvider: {},
27+
selectedProofSetId: 1,
28+
}),
29+
upload: jest.fn(async (data, callbacks) => {
30+
if (callbacks?.onUploadComplete) callbacks.onUploadComplete('mock-commp');
31+
if (callbacks?.onRootAdded) callbacks.onRootAdded();
32+
return { commp: 'mock-commp', size: data.length || 0, rootId: 1 };
33+
}),
34+
}),
1135
})),
1236
},
1337
};

0 commit comments

Comments
 (0)