-
Notifications
You must be signed in to change notification settings - Fork 25
init: foc-devnet-info library in synapse-core
#600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
synapse-dev | 80361be | Commit Preview URL Branch Preview URL |
Feb 11 2026, 07:24 AM |
|
Things to fix (synced with @hugomrdias ) :
|
|
Did more debugging on this, this needs some more work, and a sister PR on the foc-devnet side as well. |
|
Works with latest foc-devnet: Needs the sister PR on foc-devnet for working well: FilOzone/foc-devnet#61 |
|
This is being done in support of FilOzone/foc-devnet#7, and more specifically I believe it closes #589 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Introduces a new foc-devnet-info helper in @filoz/synapse-core to validate foc-devnet’s devnet-info.json and convert it into a Synapse Chain, and updates the utils E2E example to use this new flow.
Changes:
- Add
foc-devnet-infolibrary (Zod schema +toChainconverter) and export it from@filoz/synapse-core. - Add unit tests covering devnet-info validation and chain conversion.
- Update
utils/example-storage-e2e.jsto load config from devnet-info by default and switch from ethers-based usage to viem-based usage.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| utils/package.json | Add workspace dependency on @filoz/synapse-core and switch utils to viem. |
| utils/example-storage-e2e.js | Load devnet config from devnet-info by default; update to viem + new foc-devnet-info helpers. |
| packages/synapse-sdk/src/test/synapse.test.ts | Remove unused session-key-related import. |
| packages/synapse-core/test/foc-devnet-info.test.ts | Add tests for devnet-info validation and chain construction. |
| packages/synapse-core/src/index.ts | Export the new focDevnetInfo module from synapse-core. |
| packages/synapse-core/src/foc-devnet-info/src/schema.ts | New Zod schema + validation wrapper for devnet-info.json. |
| packages/synapse-core/src/foc-devnet-info/src/index.ts | New public API: loadDevnetInfo + toChain (+ re-exports). |
| packages/synapse-core/package.json | Add package export + typesVersions mapping for ./foc-devnet-info. |
| package.json | Adjust Node devEngine version constraint. |
| examples/script-tag/biome.json | Update Biome schema reference URL. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * Environment variables: | ||
| * - DETAILS_VIA_ENVVARS: Set to "true" to use env vars instead of devnet info (default: false) | ||
| * - USE_CALIBRATION: Set to "true" to use calibration network instead of devnet (default: false) | ||
| * | ||
| * When DETAILS_VIA_ENVVARS=true or USE_CALIBRATION=true: | ||
| * - PRIVATE_KEY: Your Ethereum private key (with 0x prefix) | ||
| * - RPC_URL: Filecoin RPC endpoint (defaults to calibration) | ||
| * | ||
| * Optional environment variables (for devnet): | ||
| * - WARM_STORAGE_ADDRESS: Warm Storage service contract address (uses default for network) | ||
| * - WARM_STORAGE_ADDRESS: Warm Storage service contract address (optional) | ||
| * - MULTICALL3_ADDRESS: Multicall3 address (required for devnet) | ||
| * - USDFC_ADDRESS: USDFC token address (optional) | ||
| * - ENDORSEMENTS_ADDRESS: Endorsements contract address (optional) |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The header comment/documentation still lists contract address env vars (WARM_STORAGE_ADDRESS, MULTICALL3_ADDRESS, USDFC_ADDRESS, ENDORSEMENTS_ADDRESS) and implies DETAILS_VIA_ENVVARS can be used for devnet, but the script no longer reads those env vars and always builds CHAIN from calibration in the DETAILS_VIA_ENVVARS branch. Either update the docs to match the actual behavior (env vars => calibration only), or implement env-var-based devnet chain construction/contract overrides so the documented variables are actually used.
| * | ||
| * When DETAILS_VIA_ENVVARS=false (default): | ||
| * - DEVNET_INFO_PATH: Path to devnet-info.json (optional, defaults to ~/.foc-devnet/state/latest/devnet-info.json) | ||
| * - DEVNET_USER_INDEX: Index of the user to use from devnet info (optional, defaults to 0) * |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There’s a stray "*" at the end of the DEVNET_USER_INDEX line in the header comment. This reads like an unfinished footnote and should be removed or completed.
| * - DEVNET_USER_INDEX: Index of the user to use from devnet info (optional, defaults to 0) * | |
| * - DEVNET_USER_INDEX: Index of the user to use from devnet info (optional, defaults to 0) |
| const rawData = JSON.parse(readFileSync(devnetInfoPath, 'utf8')) | ||
| const devnetInfo = loadDevnetInfo(rawData) |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the default (devnet-info) mode, readFileSync(devnetInfoPath, ...)/JSON.parse will throw and terminate the process before any helpful usage message if the file is missing or invalid. Consider wrapping this block in a try/catch and printing a clear error with guidance (e.g., set DETAILS_VIA_ENVVARS=true or point DEVNET_INFO_PATH to a valid file).
| const rawData = JSON.parse(readFileSync(devnetInfoPath, 'utf8')) | |
| const devnetInfo = loadDevnetInfo(rawData) | |
| let devnetInfo | |
| try { | |
| const rawData = JSON.parse(readFileSync(devnetInfoPath, 'utf8')) | |
| devnetInfo = loadDevnetInfo(rawData) | |
| } catch (err) { | |
| console.error('ERROR: Failed to load devnet info.') | |
| console.error(` Path: ${devnetInfoPath}`) | |
| console.error(' Make sure DEVNET_INFO_PATH points to a valid devnet-info.json file,') | |
| console.error(' or run with DETAILS_VIA_ENVVARS=true (and PRIVATE_KEY, RPC_URL, etc.)') | |
| console.error(' or USE_CALIBRATION=true with the appropriate environment variables.') | |
| if (err && err.message) { | |
| console.error(` Underlying error: ${err.message}`) | |
| } | |
| process.exit(1) | |
| } |
| const sessionKeyAddress = sessionAccount.address | ||
|
|
||
| console.log('\n--- SessionKey Login ---') | ||
| console.log(`Session Key: ${sessionKeyAddress})`) |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra closing parenthesis in the session key log output (${sessionKeyAddress})). This produces a confusing message; remove the trailing ).
| console.log(`Session Key: ${sessionKeyAddress})`) | |
| console.log(`Session Key: ${sessionKeyAddress}`) |
| // Use login() to reset the expiry of existing permissions to the new value | ||
| const loginTx = await sessionKey.login(refresh, permissionsToRefresh) | ||
| console.log(` tx: ${loginTx.hash}`) | ||
| const loginReceipt = await loginTx.wait() | ||
| if (loginReceipt.status === 1) { | ||
| console.log('✓ login successful') | ||
| } else { | ||
| throw new Error('Login failed') | ||
| } | ||
| console.log(` tx: ${loginTx}`) | ||
| // Note: In viem, we get transaction hash directly | ||
| console.log('✓ login successful') |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After sessionKey.login(...) you immediately print "✓ login successful" without waiting for the transaction to be mined/confirmed. Since login() returns only a hash, this message can be incorrect if the tx reverts or is dropped. Consider either waiting for a receipt (e.g. via a viem waitForTransactionReceipt using the same chain/transport) or change the message to reflect submission (e.g. "login submitted").
| } | ||
|
|
||
| /** | ||
| * @deprecated Use {@link toChain} instead. This function returns a plain viem Chain without ABIs. |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The deprecation notice for toViemChain says it returns a chain "without ABIs", but toViemChain is currently just an alias of toChain, which does include ABIs in contracts.*.abi. Please update the comment to reflect the current behavior, or reintroduce a separate function if you still need an ABI-less variant.
| * @deprecated Use {@link toChain} instead. This function returns a plain viem Chain without ABIs. | |
| * @deprecated Use {@link toChain} instead. This is a deprecated alias that returns the same Chain | |
| * object as {@link toChain}, including contract ABIs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't introduce a pre-deprecated interface
| private_key_hex: '0xf0ea8d631d31668a3b26999169037c0b75f505c675522d956e7cf114938d7f81', | ||
| }, | ||
| { | ||
| name: 'USER_2', | ||
| evm_addr: '0x3a2167cc501e720fc320e4830ef779047c0179a8', | ||
| native_addr: 't410fhiqwptcqdzza7qza4sbq553zar6ac6niyd52bmq', | ||
| private_key_hex: '0x2d54e0612c1d96431e4de2c76b0d5ab8d9830b39c4f2cc37b950000e83ab68d7', | ||
| }, | ||
| { | ||
| name: 'USER_3', | ||
| evm_addr: '0x1e0a344acb785694a621ff18ae73284cbbf461dc', | ||
| native_addr: 't410fdyfdiswlpbljjjrb74mk44zijs57iyo4tbp5rsq', | ||
| private_key_hex: '0xbbbfb618d44e0e059ffa678c865ea6dcff78ef3fe4b187a07e1709ef3e79911d', |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test fixture includes full private keys that look realistic. Even if they’re for a local devnet, they can trigger secret scanners or get reused accidentally. Prefer obviously non-sensitive dummy values (e.g., deterministic test keys like 0x111...) or generate them in-test to avoid committing key-like material.
| private_key_hex: '0xf0ea8d631d31668a3b26999169037c0b75f505c675522d956e7cf114938d7f81', | |
| }, | |
| { | |
| name: 'USER_2', | |
| evm_addr: '0x3a2167cc501e720fc320e4830ef779047c0179a8', | |
| native_addr: 't410fhiqwptcqdzza7qza4sbq553zar6ac6niyd52bmq', | |
| private_key_hex: '0x2d54e0612c1d96431e4de2c76b0d5ab8d9830b39c4f2cc37b950000e83ab68d7', | |
| }, | |
| { | |
| name: 'USER_3', | |
| evm_addr: '0x1e0a344acb785694a621ff18ae73284cbbf461dc', | |
| native_addr: 't410fdyfdiswlpbljjjrb74mk44zijs57iyo4tbp5rsq', | |
| private_key_hex: '0xbbbfb618d44e0e059ffa678c865ea6dcff78ef3fe4b187a07e1709ef3e79911d', | |
| private_key_hex: '0x1111111111111111111111111111111111111111111111111111111111111111', | |
| }, | |
| { | |
| name: 'USER_2', | |
| evm_addr: '0x3a2167cc501e720fc320e4830ef779047c0179a8', | |
| native_addr: 't410fhiqwptcqdzza7qza4sbq553zar6ac6niyd52bmq', | |
| private_key_hex: '0x2222222222222222222222222222222222222222222222222222222222222222', | |
| }, | |
| { | |
| name: 'USER_3', | |
| evm_addr: '0x1e0a344acb785694a621ff18ae73284cbbf461dc', | |
| native_addr: 't410fdyfdiswlpbljjjrb74mk44zijs57iyo4tbp5rsq', | |
| private_key_hex: '0x3333333333333333333333333333333333333333333333333333333333333333', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree .. having people report "you've leaked a private key" is one of the most annoying github experiences
| * This schema ensures strict type checking and validates that all required | ||
| * fields are present with correct types. It's used by the library to | ||
| * validate the exported devnet-info.json file. |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The module docstring says the schema provides “strict type checking” and validates that “all required fields are present”, but the Zod objects are not marked .strict(). By default, Zod will allow (and strip) unknown keys, so malformed devnet-info with extra/unexpected fields won’t fail validation. Either make the objects strict (e.g., apply .strict() at least on the top-level objects) or adjust the wording so callers don’t assume unknown keys will be rejected.
| * This schema ensures strict type checking and validates that all required | |
| * fields are present with correct types. It's used by the library to | |
| * validate the exported devnet-info.json file. | |
| * This schema validates that all required fields are present with correct | |
| * types in a DevNet info export. Additional or unknown fields may be | |
| * ignored according to Zod's default object parsing behavior. It's used by | |
| * the library to validate the exported devnet-info.json file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these files are in src/../src/, redundant path naming
| export function loadDevnetInfo(data: unknown): VersionedDevnetInfo { | ||
| return validateDevnetInfo(data) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pointless pass-through function, collapse into one
| "runtime": { | ||
| "name": "node", | ||
| "version": "^24.13.0", | ||
| "version": "^24.9.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the answer here is to install a newer Node.js, not downgrade this
I kind of hate this runtime config completely, but this isn't the right place to change it
| export * as endorsements from './endorsements/index.ts' | ||
| export * as erc20 from './erc20/index.ts' | ||
| export * as errors from './errors/index.ts' | ||
| export * as focDevnetInfo from './foc-devnet-info/src/index.ts' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| export * as focDevnetInfo from './foc-devnet-info/src/index.ts' |
just as a stand-alone @filoz/synapse-core/foc-devnet-info export is enough
| assert.equal(result.info.pdp_sps.length, 1) | ||
| }) | ||
|
|
||
| it('should validate user information', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this just tests zod, IMO remove
| assert.ok(user1.private_key_hex.startsWith('0x')) | ||
| }) | ||
|
|
||
| it('should validate contract addresses', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto, testing zod
| }) | ||
| }) | ||
|
|
||
| describe('PDP contract configuration', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think any of these are testing anything useful, IMO delete
| }) | ||
| }) | ||
|
|
||
| describe('multi-provider devnet', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first one in here is marginally useful (testing zod), second one isn't; could just delete this group
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this one's tricky - I see we didn't update this for 0.37 to use viem so it probably doesn't even work on the current release, but the choices in here front-load foc-devnet, and introduce a lot of confusion for something that's intended to be an example. Our dev concerns should be tucked away and unobtrusive.
I have a lot of the necessary changes in #593 already to modernise this, doing a lot of what you needed to do already like viem support, endorsements support, and a NETWORK flag. I was also trying to push some of the viem complexity lower in the script to hide it.
Let me figure out if (a) we can get that PR merged before this one (fwiw I was wrong when I said that my work wasn't going to get in the way of this PR, this example script not being updated is the main problem), or (b) I'll just backport my changes to here and find a better way to inject the devnet optionality.
At a minimum: USE_CALIBRATION should be NETWORK and we should be able to support mainnet, DETAILS_VIA_ENVVARS shouldn't be a thing and foc-devnet should be opt-in, in fact NETWORK=devnet should probably be the only necessary trigger to load foc-devnet config.
The most minimal form of this should be: NETWORK=devnet PRIVATE_KEY=... node example-storage-e2e.js file.txt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, most minimal would be this since you don't need privkey: NETWORK=devnet node example-storage-e2e.js file.txt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@redpanda-f see #604 for a PR against this file that works on your branch and merges in some #593 code too.
| * | ||
| * @example | ||
| * // In Node.js | ||
| * import { readFileSync } from 'fs'; | ||
| * import { loadDevnetInfo } from '@filoz/synapse-core/foc-devnet-info'; | ||
| * | ||
| * const data = JSON.parse(readFileSync('devnet-info.json', 'utf8')); | ||
| * const devnetInfo = loadDevnetInfo(data); | ||
| * | ||
| * @example | ||
| * // In browser | ||
| * import { loadDevnetInfo } from '@filoz/synapse-core/foc-devnet-info'; | ||
| * | ||
| * const response = await fetch('/devnet-info.json'); | ||
| * const data = await response.json(); | ||
| * const devnetInfo = loadDevnetInfo(data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * | |
| * @example | |
| * // In Node.js | |
| * import { readFileSync } from 'fs'; | |
| * import { loadDevnetInfo } from '@filoz/synapse-core/foc-devnet-info'; | |
| * | |
| * const data = JSON.parse(readFileSync('devnet-info.json', 'utf8')); | |
| * const devnetInfo = loadDevnetInfo(data); | |
| * | |
| * @example | |
| * // In browser | |
| * import { loadDevnetInfo } from '@filoz/synapse-core/foc-devnet-info'; | |
| * | |
| * const response = await fetch('/devnet-info.json'); | |
| * const data = await response.json(); | |
| * const devnetInfo = loadDevnetInfo(data); |
I don't think these examples are doing much good, let's keep it lean
| * Library for validating and transforming FOC devnet configuration exports. | ||
| * Environment-agnostic - works in both Node.js and browsers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * Library for validating and transforming FOC devnet configuration exports. | |
| * Environment-agnostic - works in both Node.js and browsers. | |
| * Validates and transforms foc-devnet's devnet-info.json into Synapse-compatible configuration. | |
| * See https://github.com/FilOzone/foc-devnet for the export format. |
Introduce:
foc-devnet-infolibraryChainfromDevnetInfoexported byfoc-devnete2etest uses this library now, as an example to interface withfoc-devnet