Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
878e5ed
Add Whitelist program
GuidoDipietro Dec 17, 2025
57af08c
Settler: Intent lifecycle
GuidoDipietro Dec 17, 2025
cc10fad
Settler: Proposal Lifecycle
GuidoDipietro Dec 17, 2025
cf0e619
Settler: Signatures
GuidoDipietro Dec 17, 2025
f5e81b9
Fix tests
GuidoDipietro Dec 17, 2025
2f91061
Merge branch 'solana/1-whitelist' into solana/2-settler-intent-lifecycle
GuidoDipietro Dec 17, 2025
f1545be
Trim tests to this PRs features
GuidoDipietro Dec 17, 2025
9bd0e0e
Rm signatures utils as not relevant in this PR
GuidoDipietro Dec 17, 2025
ea31118
Trim SDK to match this PRs features
GuidoDipietro Dec 17, 2025
0707a85
Trim tests to this PRs features
GuidoDipietro Dec 17, 2025
1b87e10
Merge branch 'solana/2-settler-intent-lifecycle' into solana/3-settle…
GuidoDipietro Dec 17, 2025
890d5de
Merge branch 'solana/3-settler-proposal-lifecycle' into solana/4-sett…
GuidoDipietro Dec 17, 2025
d05f128
Add remaining files from original PR
GuidoDipietro Dec 17, 2025
3d93df3
EVM: Deploy contracts to Ethereum (#51)
alavarello Dec 17, 2025
a20c769
chore: update readme
facuspagnuolo Dec 18, 2025
ea6b0fb
Check deadlines on macros instead of ix fn body consistently
GuidoDipietro Dec 22, 2025
fc51d1c
Refactor if-return-err to require
GuidoDipietro Dec 22, 2025
804e2a4
Code review: simplify set admin process
GuidoDipietro Dec 30, 2025
a8b019b
Code review: Remove updated_by and last_update from EntityRegistry
GuidoDipietro Dec 30, 2025
eff0a23
Code review: rename Whitelist to Controller/Allowlist
GuidoDipietro Dec 30, 2025
90c6e3c
Code review: rm EntityRegistry status and close when not in allowlist
GuidoDipietro Dec 30, 2025
5cfce2b
Several fixes in Controller code
GuidoDipietro Dec 30, 2025
4282a1f
Code review: address other comments
GuidoDipietro Dec 30, 2025
b918391
Code review: add license
GuidoDipietro Dec 30, 2025
44a93c6
Merge branch 'solana/1-whitelist' into solana/2-settler-intent-lifecycle
GuidoDipietro Dec 30, 2025
e916fa1
Code review: adapt Settler to Controller changes
GuidoDipietro Dec 30, 2025
a1eb61d
Code review: rename controller::GlobalSettings to ControllerSettings,…
GuidoDipietro Dec 30, 2025
5f8eb31
Code review: rm is_paused from SettlerSettings
GuidoDipietro Dec 30, 2025
f42465b
Merge branch 'solana/2-settler-intent-lifecycle' into solana/3-settle…
GuidoDipietro Dec 30, 2025
1039442
Code review: adapt Settler to match Controller changes
GuidoDipietro Dec 30, 2025
435b7dc
Rm unused is_paused flag
GuidoDipietro Dec 30, 2025
5e4eb54
Merge branch 'solana/2-settler-intent-lifecycle' into solana/3-settle…
GuidoDipietro Dec 30, 2025
b638369
Fix lint
GuidoDipietro Dec 30, 2025
3130209
Code review: rename proposal_creator to creator
GuidoDipietro Dec 30, 2025
efbfea9
Fix lint
GuidoDipietro Dec 30, 2025
876abc6
Merge branch 'solana/3-settler-proposal-lifecycle' into solana/4-sett…
GuidoDipietro Dec 30, 2025
1c1c0c9
Code review: adapt Settler for changes in Controller
GuidoDipietro Dec 30, 2025
e1ef9ed
Code review: several comments
GuidoDipietro Jan 5, 2026
c715467
Code review: context() pattern in tests
GuidoDipietro Jan 5, 2026
0d815fa
Merge branch 'solana/1-whitelist' into solana/2-settler-intent-lifecycle
GuidoDipietro Jan 5, 2026
40d2ad6
Fix lint and merge errors
GuidoDipietro Jan 5, 2026
89ddecc
Code review: several comments
GuidoDipietro Jan 5, 2026
38d0f18
Merge branch 'solana/2-settler-intent-lifecycle' into solana/3-settle…
GuidoDipietro Jan 5, 2026
4d99fd4
Merge branch 'solana/3-settler-proposal-lifecycle' into solana/4-sett…
GuidoDipietro Jan 5, 2026
ba1d144
Code review: change crate::controller to controller
GuidoDipietro Jan 5, 2026
571ea10
Merge branch 'solana/3-settler-proposal-lifecycle' into solana/4-sett…
GuidoDipietro Jan 5, 2026
0ff6529
(1) Add Controller program (#45)
GuidoDipietro Jan 6, 2026
e690d3c
Merge branch 'solana/settler' into solana/3-settler-proposal-lifecycle
GuidoDipietro Jan 6, 2026
1ac6503
Revert "Merge branch 'solana/settler' into solana/3-settler-proposal-…
GuidoDipietro Jan 6, 2026
9fd1cc8
Merge branch 'solana/settler' into solana/3-settler-proposal-lifecycle
GuidoDipietro Jan 6, 2026
391eb43
Correct controller.test.ts file
GuidoDipietro Jan 6, 2026
f7d2a12
Merge branch 'solana/3-settler-proposal-lifecycle' into solana/4-sett…
GuidoDipietro Jan 6, 2026
ce6dba5
Code review: remove batch capabilities from claim_stale_proposal
GuidoDipietro Jan 7, 2026
286e8de
Merge branch 'solana/3-settler-proposal-lifecycle' into solana/4-sett…
GuidoDipietro Jan 7, 2026
b869e79
Merge branch 'solana/settler' into solana/4-settler-signatures
GuidoDipietro Jan 9, 2026
80fed04
Code review: remove unused instruction
GuidoDipietro Jan 20, 2026
c260c6c
Refactor tests to use context() pattern
GuidoDipietro Jan 20, 2026
7170904
Fix lint
GuidoDipietro Jan 20, 2026
b79f20c
Code review: add_validator_sig EntityRegistry seed checks
GuidoDipietro Jan 21, 2026
d7bc7ee
Merge branch 'solana/4-settler-signatures' into solana/test-refactor
GuidoDipietro Jan 21, 2026
80847c6
Merge branch 'solana/settler' into solana/test-refactor
GuidoDipietro Jan 21, 2026
b6bf5c7
Code review: fix context() pattern
GuidoDipietro Jan 23, 2026
8f05b0f
Code review: extract repeated logic to utils in Settler tests
GuidoDipietro Jan 23, 2026
592acf6
Code review: EntityType enum values
GuidoDipietro Jan 26, 2026
8793355
Code review: Add test case + Settler test nits
GuidoDipietro Jan 26, 2026
cc25413
Code review: Change context() namein test suite
GuidoDipietro Jan 26, 2026
ea19ba1
Code review: split test/helpers/helpers.ts into multiple files
GuidoDipietro Jan 26, 2026
d7891b6
Fix comment
GuidoDipietro Jan 26, 2026
1900037
Code review: remove add_axia_sig and add_validator_sig (re-done on an…
GuidoDipietro Jan 28, 2026
a1bf4c0
Code review: refactor tests/helpers
GuidoDipietro Jan 28, 2026
6a10020
Code review: create_intent describe
GuidoDipietro Jan 29, 2026
202d491
Code review: remove test case
GuidoDipietro Jan 30, 2026
39625b6
Code review: extend_intent
GuidoDipietro Feb 2, 2026
f506cc2
Code review: claim_stale_intent
GuidoDipietro Feb 3, 2026
8d24fdf
Code review: create_proposal
GuidoDipietro Feb 3, 2026
d758f12
Code review: tests/helpers/proposals.ts tidy up
GuidoDipietro Feb 4, 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
6 changes: 3 additions & 3 deletions packages/svm/programs/controller/src/types/entity_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use anchor_lang::prelude::*;
#[repr(u8)]
#[derive(Copy, Clone, AnchorSerialize, AnchorDeserialize)]
pub enum EntityType {
Validator = 1,
Axia = 2,
Solver = 3,
Validator = 0,
Axia = 1,
Solver = 2,
}

impl anchor_lang::Space for EntityType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ pub struct AddAxiaSig<'info> {
pub solver: Signer<'info>,

#[account(
seeds = [b"entity-registry", &[EntityType::Solver as u8 + 1], solver.key().as_ref()],
seeds = [b"entity-registry", &[EntityType::Solver as u8], solver.key().as_ref()],
bump = solver_registry.bump,
seeds::program = controller::ID,
)]
pub solver_registry: Box<Account<'info, EntityRegistry>>,

#[account(
seeds = [b"entity-registry", &[EntityType::Axia as u8 + 1], axia_registry.entity_pubkey.as_ref()],
seeds = [b"entity-registry", &[EntityType::Axia as u8], axia_registry.entity_pubkey.as_ref()],
bump = axia_registry.bump,
seeds::program = controller::ID,
)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct AddValidatorSig<'info> {
pub solver: Signer<'info>,

#[account(
seeds = [b"entity-registry", &[EntityType::Solver as u8 + 1], solver.key().as_ref()],
seeds = [b"entity-registry", &[EntityType::Solver as u8], solver.key().as_ref()],
bump = solver_registry.bump,
seeds::program = controller::ID,
)]
Expand All @@ -38,7 +38,7 @@ pub struct AddValidatorSig<'info> {
pub fulfilled_intent: SystemAccount<'info>,

#[account(
seeds = [b"entity-registry", &[EntityType::Validator as u8 + 1], validator_registry.entity_pubkey.as_ref()],
seeds = [b"entity-registry", &[EntityType::Validator as u8], validator_registry.entity_pubkey.as_ref()],
bump = validator_registry.bump,
seeds::program = controller::ID,
)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct CreateIntent<'info> {
pub solver: Signer<'info>,

#[account(
seeds = [b"entity-registry", &[EntityType::Solver as u8 + 1], solver.key().as_ref()],
seeds = [b"entity-registry", &[EntityType::Solver as u8], solver.key().as_ref()],
bump = solver_registry.bump,
seeds::program = controller::ID
)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct CreateProposal<'info> {
pub solver: Signer<'info>,

#[account(
seeds = [b"entity-registry", &[EntityType::Solver as u8 + 1], solver.key().as_ref()],
seeds = [b"entity-registry", &[EntityType::Solver as u8], solver.key().as_ref()],
bump = solver_registry.bump,
seeds::program = controller::ID,
)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct ExecuteProposal<'info> {
pub solver: Signer<'info>,

#[account(
seeds = [b"entity-registry", &[EntityType::Solver as u8 + 1], solver.key().as_ref()],
seeds = [b"entity-registry", &[EntityType::Solver as u8], solver.key().as_ref()],
bump = solver_registry.bump,
seeds::program = controller::ID,
)]
Expand Down
6 changes: 3 additions & 3 deletions packages/svm/sdks/controller/Controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import * as ControllerIDL from '../../target/idl/controller.json'
import { Controller } from '../../target/types/controller'

export const EntityType = {
Validator: 1,
Axia: 2,
Solver: 3,
Validator: 0,
Axia: 1,
Solver: 2,
} as const

export type EntityType = (typeof EntityType)[keyof typeof EntityType]
Expand Down
25 changes: 9 additions & 16 deletions packages/svm/sdks/settler/Settler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Settler } from '../../target/types/settler'
import { EntityType } from '../controller/Controller'
import {
CreateIntentParams,
CreateProposalParams,
ExtendIntentParams,
IntentEvent,
OpType,
Expand Down Expand Up @@ -111,18 +112,13 @@ export default class SettlerSDK {
return ix
}

async createProposalIx(
intentHashHex: string,
instructions: ProposalInstruction[],
fees: TokenFee[],
deadline: number,
isFinal = true
): Promise<web3.TransactionInstruction> {
async createProposalIx(intentHashHex: string, params: CreateProposalParams): Promise<web3.TransactionInstruction> {
const { instructions, fees, deadline, isFinal } = params
const parsedInstructions = this.parseProposalInstructions(instructions)
const parsedFees = this.parseTokenFees(fees)

const ix = await this.program.methods
.createProposal(parsedInstructions, parsedFees, new BN(deadline), isFinal)
.createProposal(parsedInstructions, parsedFees, new BN(deadline), isFinal ?? false)
.accountsPartial({
solver: this.getSignerKey(),
solverRegistry: this.getEntityRegistryPubkey(EntityType.Solver, this.getSignerKey()),
Expand Down Expand Up @@ -225,15 +221,13 @@ export default class SettlerSDK {
}

getIntentKey(intentHashHex: string): web3.PublicKey {
const intentHash = Buffer.from(intentHashHex, 'hex')
if (intentHash.length != 32) throw new Error(`Intent hash must be 32 bytes: ${intentHashHex}`)
const intentHash = Buffer.from(this.parseIntentHashHex(intentHashHex))

return web3.PublicKey.findProgramAddressSync([Buffer.from('intent'), intentHash], this.program.programId)[0]
}

getFulfilledIntentKey(intentHashHex: string): web3.PublicKey {
const intentHash = Buffer.from(intentHashHex, 'hex')
if (intentHash.length != 32) throw new Error(`Intent hash must be 32 bytes: ${intentHashHex}`)
const intentHash = Buffer.from(this.parseIntentHashHex(intentHashHex))

return web3.PublicKey.findProgramAddressSync(
[Buffer.from('fulfilled-intent'), intentHash],
Expand All @@ -242,8 +236,7 @@ export default class SettlerSDK {
}

getProposalKey(intentHashHex: string, solverPubkey?: web3.PublicKey): web3.PublicKey {
const intentHash = Buffer.from(intentHashHex, 'hex')
if (intentHash.length != 32) throw new Error(`Intent hash must be 32 bytes: ${intentHashHex}`)
this.parseIntentHashHex(intentHashHex)

const intentKey = this.getIntentKey(intentHashHex)
const solver = solverPubkey || this.getSignerKey()
Expand Down Expand Up @@ -275,13 +268,13 @@ export default class SettlerSDK {
}

private parseIntentHashHex(intentHashHex: string): number[] {
const intentHash = Buffer.from(intentHashHex, 'hex')
const intentHash = Buffer.from(intentHashHex.slice(2), 'hex')
if (intentHash.length != 32) throw new Error(`Intent hash must be 32 bytes: ${intentHashHex}`)
return Array.from(intentHash)
}

private parseIntentNonceHex(nonceHex: string): number[] {
const nonce = Buffer.from(nonceHex, 'hex')
const nonce = Buffer.from(nonceHex.slice(2), 'hex')
if (nonce.length != 32) throw new Error(`Nonce must be 32 bytes: ${nonceHex}`)
return Array.from(nonce)
}
Expand Down
7 changes: 7 additions & 0 deletions packages/svm/sdks/settler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ export type ExtendIntentParams = {
moreEventsHex?: IntentEvent[]
}

export type CreateProposalParams = {
instructions: ProposalInstruction[]
fees: TokenFee[]
deadline: number
isFinal?: boolean
}

export type ProposalInstructionAccountMeta = {
pubkey: web3.PublicKey
isSigner: boolean
Expand Down
2 changes: 1 addition & 1 deletion packages/svm/tests/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import path from 'path'
import ControllerSDK, { EntityType } from '../sdks/controller/Controller'
import * as ControllerIDL from '../target/idl/controller.json'
import { Controller } from '../target/types/controller'
import { expectTransactionError, randomKeypair, randomPubkey, toLamports } from './helpers/helpers'
import { expectTransactionError, randomKeypair, randomPubkey, toLamports } from './helpers'
import { makeTxSignAndSend, warpSeconds } from './utils'

describe('Controller', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/svm/tests/helpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const ACCOUNT_CLOSE_FEE = 5000 // Fee for closing accounts

// Test constants for data
export const DEFAULT_DATA_HEX = '010203'
export const DEFAULT_TOPIC_HEX = Buffer.from(Array(32).fill(1)).toString('hex')
export const DEFAULT_TOPIC_HEX = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
export const DEFAULT_EVENT_DATA_HEX = '040506'
export const EMPTY_DATA_HEX = ''
export const TEST_DATA_HEX_1 = '070809'
Expand Down
20 changes: 20 additions & 0 deletions packages/svm/tests/helpers/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Keypair } from '@solana/web3.js'
import { LiteSVMProvider } from 'anchor-litesvm'

import ControllerSDK, { EntityType } from '../../sdks/controller/Controller'
import { makeTxSignAndSend } from '../utils'

/**
* Creates an allowlisted entity (validator, axia, or solver)
*/
export async function createAllowlistedEntity(
controllerSdk: ControllerSDK,
provider: LiteSVMProvider,
entityType: EntityType,
entityKeypair?: Keypair
): Promise<Keypair> {
const entity = entityKeypair || Keypair.generate()
const allowlistIx = await controllerSdk.setAllowedEntityIx(entityType, entity.publicKey)
await makeTxSignAndSend(provider, allowlistIx)
return entity
}
Loading