Skip to content
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
6be6998
Baseline super-good-enough cert
Kubuxu Nov 12, 2025
374acc3
stub decodeEndorsements
wjmelements Nov 12, 2025
5a4ec65
preferEndorsements
wjmelements Nov 12, 2025
8ce3807
start decoding endorsements
Kubuxu Nov 13, 2025
ea1c8f8
notAfter as timesetamp
wjmelements Nov 13, 2025
b2538d1
encodeEndorsements
wjmelements Nov 13, 2025
174a7e8
mv cert.ts to utils
wjmelements Nov 14, 2025
0959768
utils export from cert.ts
wjmelements Nov 14, 2025
8fdb6bf
fix test
wjmelements Nov 14, 2025
67af7c0
test that createContexts prefers endorsements
wjmelements Nov 14, 2025
a34808c
encode/decode certs with domain separator
wjmelements Nov 14, 2025
953f4c8
add cert test
wjmelements Nov 15, 2025
c4ea7c7
Merge remote-tracking branch 'origin/master' into feat/super-good-eno…
wjmelements Nov 15, 2025
e5236ad
add tools/endorse-sp.js
wjmelements Nov 15, 2025
ebebd81
increase timeout for CI
wjmelements Nov 15, 2025
344d9d2
make the decodeEndorsements a bit simpler
Kubuxu Nov 15, 2025
c81971a
add more tests
Kubuxu Nov 15, 2025
7c784b7
Update packages/synapse-core/src/utils/cert.ts
wjmelements Nov 16, 2025
cdcf6d4
rm sinon
wjmelements Nov 17, 2025
7c58dd8
Update packages/synapse-core/src/utils/cert.ts
wjmelements Nov 17, 2025
6874d4a
cleanup
wjmelements Nov 17, 2025
77a4524
Update packages/synapse-core/src/utils/cert.ts
wjmelements Nov 17, 2025
1318554
Merge remote-tracking branch 'origin/master' into feat/endorsement-ce…
wjmelements Nov 25, 2025
f1a66ef
disallow undefined chainId in decodeEndorsement
wjmelements Nov 25, 2025
72047d7
accept any of the preferred endorsements
wjmelements Nov 26, 2025
57c44a7
Merge remote-tracking branch 'origin/master' into feat/endorsement-ce…
wjmelements Jan 13, 2026
9f55a11
remove certs
wjmelements Jan 13, 2026
1aace20
wagmi
wjmelements Jan 13, 2026
b236a21
constants
wjmelements Jan 13, 2026
8020db0
EndorsementsService
wjmelements Jan 13, 2026
3e91700
plumbing
wjmelements Jan 14, 2026
c50a632
import type
wjmelements Jan 14, 2026
422f105
add endorsements mock and restore test
wjmelements Jan 14, 2026
2a96464
add endorsements script to examples/cli
wjmelements Jan 15, 2026
c76237c
delete keystore when init with pk
wjmelements Jan 15, 2026
a7718ff
Revert "delete keystore when init with pk"
wjmelements Jan 15, 2026
9410618
fix lint
wjmelements Jan 15, 2026
1734d72
isCancel
wjmelements Jan 15, 2026
59c313b
serviceURL
wjmelements Jan 15, 2026
7c10429
Merge remote-tracking branch 'origin/master' into feat/endorsement-set
wjmelements Jan 15, 2026
a8696ba
lint
wjmelements Jan 15, 2026
6d429c2
decodePDPCapabilities is not async
wjmelements Jan 20, 2026
8628eff
Merge remote-tracking branch 'origin/master' into feat/endorsement-set
wjmelements Jan 20, 2026
dacf3f8
Revert "chore: re-add `getMaxProvingPeriod` and `challengeWindow` fun…
wjmelements Jan 20, 2026
2423079
getContract
wjmelements Jan 20, 2026
cb582d8
test fallback on ping failure
wjmelements Jan 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions examples/cli/src/commands/endorse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import {
confirm,
intro,
log,
outro,
select,
spinner,
text,
} from '@clack/prompts'
import { getChain } from '@filoz/synapse-core/chains'
import { type Command, command } from 'cleye'
import type { Address, Hash } from 'viem'
import { readContract, simulateContract, writeContract } from 'viem/actions'
import { privateKeyClient } from '../client.ts'
import { globalFlags } from '../flags.ts'

class EndorsementsContract {
constructor(client) {
this.client = client

const chain = getChain(client.chain.id)
this.contract = chain.contracts.endorsements
}

async getProviderIds(): number[] {
const providerIds = await readContract(this.client, {
...this.contract,
functionName: 'getProviderIds',
})
return providerIds.map(Number)
}

async removeProviderId(providerId: number): Hash {
const { request } = await simulateContract(this.client, {
...this.contract,
account: this.client.account,
functionName: 'removeProviderId',
args: [providerId],
})
return await writeContract(this.client, request)
}

async addProviderId(providerId: number): Hash {
const { request } = await simulateContract(this.client, {
...this.contract,
account: this.client.account,
functionName: 'addProviderId',
args: [providerId],
})
return await writeContract(this.client, request)
}

async owner(): Address {
return await readContract(this.client, {
...this.contract,
functionName: 'owner',
})
}
}

export const endorse: Command = command(
{
name: 'endorse',
description: 'Endorse Service Provider',
alias: 'e',
flags: {
...globalFlags,
},
},
async (argv) => {
intro('Endorsements')
log.info('Loading account')
const { client } = privateKeyClient(argv.flags.chain)

const endorsements = new EndorsementsContract(client)

while (true) {
const [owner, endorsed] = await Promise.all([
endorsements.owner(),
endorsements.getProviderIds(),
])
const lines = [
`Current User: ${client.account.address}`,
`Owner: ${owner}`,
`Endorsements: ${endorsed.length}`,
...endorsed.map((providerId) => `- ${providerId}`),
]
log.info(lines.join('\n'))

const isOwner = client.account.address === owner

const action = await select({
message: 'Select an action',
options: [
{ value: 'refresh' },
{ value: 'addProvider', disabled: !isOwner },
{ value: 'removeProvider', disabled: !isOwner },
{ value: 'transferOwnership', disabled: !isOwner },
{ value: 'exit' },
],
})
switch (action) {
case 'refresh': {
continue
}
case 'exit': {
outro('bye!')
process.exit(0)
break
}
case 'removeProvider': {
const providerId = await select({
message: '',
options: [
{ value: 'go back' },
...endorsed.map((providerId) => {
return {
value: String(providerId),
}
}),
],
})
if (providerId !== 'go back') {
if (await confirm({ message: `Remove provider ${providerId}?` })) {
const txSpin = spinner()
txSpin.start(`Submitting transaction`)
try {
const txHash = await endorsements.removeProviderId(
Number(providerId)
)
txSpin.stop(`Transaction submitted: ${txHash}`)
} catch (error) {
txSpin.stop(`Failed to remove ${providerId}: ${error.message}`)
}
}
}
break
}
case 'addProvider': {
const providerId = await text({
message: '',
validate(value) {
const number = Number(value)
if (!Number.isInteger(number) || number <= 0) {
return 'providerId should be a positive integer'
}
},
})
if (await confirm({ message: `Add provider ${providerId}?` })) {
const txSpin = spinner()
txSpin.start(`Submitting transaction`)
try {
const txHash = await endorsements.addProviderId(
Number(providerId)
)
txSpin.stop(`Transaction submitted: ${txHash}`)
} catch (error) {
txSpin.stop(`Failed to remove ${providerId}: ${error.message}`)
}
}
break
}
default: {
log.error('Unsupported option')
}
}
}
}
)
2 changes: 2 additions & 0 deletions examples/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { cli } from 'cleye'
import { datasetTerminate } from './commands/dataset-terminate.ts'
import { datasets } from './commands/datasets.ts'
import { deposit } from './commands/deposit.ts'
import { endorse } from './commands/endorse.ts'
import { fund } from './commands/fund.ts'
import { init } from './commands/init.ts'
import { pay } from './commands/pay.ts'
Expand All @@ -20,6 +21,7 @@ const argv = cli({
pay,
fund,
deposit,
endorse,
upload,
datasets,
datasetTerminate,
Expand Down
Loading
Loading