Skip to content

Conversation

@wjmelements
Copy link
Contributor

@wjmelements wjmelements commented Nov 15, 2025

Co-authored by @Kubuxu
Reviewer @rvagg @hugomrdias

Context

prefer to use at least one endorsed SP by default

For #312, when we are selecting the providers, we prefer that at least one provider has a prime endorsement.
If there aren't any prime endorsements, we do not panic.
We will surface these endorsements as product capabilities in the service provider registry.

Changes

  • define EIP712 type struct and domain for Endorsement Certificates
  • sign, encode, and decode endorsement certificates as product capabilities
  • selectProviderWithPing returns null on failure instead of throwing an exception
  • update createContext and createContexts to preferEndorsements in smartSelectProvider if no other providers have been selected
  • provide minimum script for signing endorsement certificates

ref: FIL-13, FIL-14

@wjmelements wjmelements requested a review from rvagg November 15, 2025 05:50
@github-project-automation github-project-automation bot moved this to 📌 Triage in FS Nov 15, 2025
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Nov 15, 2025

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
synapse-dev 72047d7 Commit Preview URL

Branch Preview URL
Nov 26 2025, 07:50 PM

@wjmelements wjmelements added the enhancement New feature or request label Nov 15, 2025
notAfter: bytesToBigInt(data.slice(8, 16)),
signature: bytesToHex(data.slice(16)),
}
const address = await recoverTypedDataAddress({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked into why this was async (in principle it should not be). It is only because of this async import:

export async function recoverPublicKey({
  hash,
  signature,
}: RecoverPublicKeyParameters): Promise<RecoverPublicKeyReturnType> {
  const hashHex = isHex(hash) ? hash : toHex(hash)

  const { secp256k1 } = await import('@noble/curves/secp256k1')

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, that's nasty, but oh well

Kubuxu and others added 3 commits November 15, 2025 16:26
@wjmelements
Copy link
Contributor Author

PRIME_ENDORSEMENTS

I think this belongs in constants.ts

The reason not to move this is that it would then be exported, and I don't think we intend to export it. if you want to export it I can make the change.

export * from './constants.ts'

@rvagg @hugomrdias let me know if you agree

@wjmelements wjmelements requested a review from rvagg November 17, 2025 19:25
Comment on lines +76 to +85
if (hexData.length !== 164) {
return {
address: null,
endorsement: {
nonce: 0n,
notAfter: 0n,
signature: '0x',
},
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just throw err?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to reduce use of try/catch for expected situations because it can mask unexpected situations

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you pls move this to examples/cli and make a command for this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all of those commands in cli are only using calibration. None of them consult env. How do you want those to select the chain?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes will fix !

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hugomrdias are we blocked on that? should we land this in place and then move it later or do we need to resolve #469 first?

Copy link
Member

@hugomrdias hugomrdias Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i just dont like random cli files in the core folder we have the utils folder for that and now the examples/cli for more structured cli/nodejs stuff.

but yes we can land this and fix later

@github-project-automation github-project-automation bot moved this from 📌 Triage to ⌨️ In Progress in FS Nov 25, 2025
notAfter: EXPIRY,
})
console.log('Provider:', providerId)
console.log('Endorsement:', encoded)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: curio interface for hex

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


const PRIVATE_KEY = process.env.PRIVATE_KEY
const ETH_RPC_URL = process.env.ETH_RPC_URL || 'https://api.calibration.node.glif.io/rpc/v1'
const EXPIRY = process.env.EXPIRY || BigInt(Math.floor(Date.now() / 1000)) + 10368000n
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment that this is (now + 4 months)

}

const PRIVATE_KEY = process.env.PRIVATE_KEY
const ETH_RPC_URL = process.env.ETH_RPC_URL || 'https://api.calibration.node.glif.io/rpc/v1'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe these should be ??

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not strictly necessary but would provide clearer error cases - if you set ETH_RPC_URL to something falsy then it's going to use the default where it probably should error, e.g. "can't connect to RPC provider '0'

}
} catch {
// Skip invalid endorsements
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can remove this catch now

Copy link
Contributor Author

@wjmelements wjmelements Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would need to make sure that signatures that fail to recover don't throw. Should have a test case covering this in case that behavior changes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 looks to me like a failure here would be of the fatal kind now since you're doing so much in decodeEndorsement

const signature = await signTypedData(client, {
account: client.account,
domain: {
name: 'Storage Endorsement',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be a const

(results: [ProviderInfo[], ProviderInfo[]], provider: ProviderInfo) => {
results[
preferEndorsements.some(
(endorsement: Address) => endorsement in (provider.products.PDP?.data.endorsements ?? {})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be cleaned up by pulling provider.products.PDP?.data.endorsements ?? {} into a local variable inside the arrow func, then we might be able to avoid the multi-line mess that's making this hard to read

@rvagg
Copy link
Collaborator

rvagg commented Dec 1, 2025

Overall fine by me, just a few minor suggestions in there and one major concern to be resolved regarding the CLI tool.
We also need that Curio change dealt with to make this useful.
I think one of us can pick this up this week so it doesn't rest on William, who has much more important things to attend to now!

@linear
Copy link

linear bot commented Dec 1, 2025

Copy link
Collaborator

@rvagg rvagg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocked by decision @ #540
Comes down to resourcing, do we spend the time to implement an alternative and can we afford the time for that.

@github-project-automation github-project-automation bot moved this from 🐱 Todo to ⌨️ In Progress in FS Jan 8, 2026
@wjmelements
Copy link
Contributor Author

Blocked by decision @ #540 Comes down to resourcing, do we spend the time to implement an alternative and can we afford the time for that.

Much of this work can be reused with the Endorsement Registry approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: ⌨️ In Progress

Development

Successfully merging this pull request may close these issues.

6 participants