Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
8aed042
added oracle limit support
santy311 Jun 9, 2025
805c8a1
WIP: fixed test case for oracle limit
santy311 Jun 9, 2025
bd533b4
added passthrough action support
santy311 Jun 10, 2025
2fe58f0
WIP: added oracle data reader
santy311 Jun 11, 2025
1046066
modified OracleTokenLimit
santy311 Jun 11, 2025
25a6436
added sol oracle limit
santy311 Jun 11, 2025
50d61ba
fixed oracle token transfer test case
santy311 Jun 13, 2025
19f4cd7
added CU count logs
santy311 Jun 13, 2025
57bee0e
added more oracle mints support
santy311 Jun 13, 2025
18d01c0
read directly from pyth oracle data
santy311 Jun 15, 2025
02d2d9c
removed complex feed id fetch logic
santy311 Jun 15, 2025
449af9c
fix stupid comments
santy311 Jun 15, 2025
9cd1b87
Merge remote-tracking branch 'origin/main' into santhosh/oracle-limit
santy311 Jun 27, 2025
d462321
changed error code after merge conflict
santy311 Jun 27, 2025
848edaf
changed error code number for oracle limit
santy311 Jun 27, 2025
0a4aa49
scope support added
santy311 Jul 5, 2025
2680569
Merge remote-tracking branch 'origin/main' into santhosh/oracle-limit…
santy311 Jul 5, 2025
0c77ff0
fixed merge conflict issues
santy311 Jul 5, 2025
a47b68c
removed long mapping
santy311 Jul 16, 2025
61e98d9
Merge remote-tracking branch 'origin/main' into santhosh/oracle-limit…
santy311 Jul 16, 2025
19ab2d0
oracle test added for new scope mapping states
santy311 Jul 16, 2025
d543931
imported oracle mapper states from mapper repo
santy311 Jul 25, 2025
6345368
added display support for test debugging
santy311 Jul 25, 2025
f4268fe
removed pyth as scope is derived from pyth
santy311 Aug 1, 2025
211367c
fixed merge conflict
santy311 Aug 4, 2025
c113c68
added stale check for oracle prices
santy311 Aug 4, 2025
ca69b03
changed oracle mapper branch to main
santy311 Aug 4, 2025
15a6569
oracle reccuring limit
santy311 Aug 10, 2025
95a29e1
fixed formatting
santy311 Aug 10, 2025
1b5954e
Merge remote-tracking branch 'origin/main' into santhosh/oracle-limit…
santy311 Aug 11, 2025
d4613bd
oracle fixes
santy311 Aug 11, 2025
5bac70d
added EUR support
santy311 Aug 12, 2025
ca1d940
oracle_recurring_limit_window_reset debug
santy311 Aug 12, 2025
c3ac2cd
fixed CU limit for program scope test
santy311 Aug 12, 2025
6dabac6
Merge remote-tracking branch 'origin/main' into santhosh/oracle-limit…
santy311 Aug 13, 2025
c410d78
Merge remote-tracking branch 'origin/main' into santhosh/oracle-limit…
santy311 Sep 22, 2025
a4d532f
WIP: oracle refactor
santy311 Sep 23, 2025
94281b2
Merge remote-tracking branch 'origin/main' into santhosh/oracle-limit…
santy311 Oct 7, 2025
bb0afdc
removed duplicate role fetch helper
santy311 Oct 7, 2025
a6053b1
fixed oracle test cases for sign v2.
santy311 Oct 7, 2025
958ae3f
sdk and CLI support
santy311 Oct 14, 2025
81fda70
replaced owner check with address check
santy311 Oct 14, 2025
e96b774
replaced key with owner
santy311 Oct 14, 2025
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
89 changes: 76 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions cli/dumps/mapping.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"pubkey": "FbeuRDWwLvZWEU3HNtaLoYKagw9rH1NvmjpRMpjMwhDw",
"account": {
"lamports": 1468560,
"data": [
"ASgQWPWCd2TeA+fvXK6Z2qNd9rPpSvLyfN/8IrV2xhjoAAEACQApAP4ABpuIV/6rgYT7aH9jRhjANdrEOdwa6ztVmKDwAAAAAAEpAQkAAP////8=",
"base64"
],
"owner": "9WM51wrB9xpRzFgYJHocYNnx4DF6G6ee2eB44ZGoZ8vg",
"executable": false,
"rentEpoch": 18446744073709551615,
"space": 83
}
}
14 changes: 14 additions & 0 deletions cli/dumps/scope.json

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,45 @@ pub fn parse_permission_from_json(permission_json: &Value) -> Result<Permission>
recurring,
})
},
Some("oracle") => {
// Oracle value-based limit, optional recurring
// Supported fields:
// - baseAsset: "USD" | "EUR" (preferred) OR baseAssetType: number (u8)
// - valueLimit: u64
// - passthrough: bool (default false)
// - recurring: { window: u64 } (optional)
let base_asset_type = if let Some(base_str) = permission_json["baseAsset"].as_str() {
match base_str {
"USD" | "usd" => 0u8,
"EUR" | "eur" => 1u8,
other => return Err(anyhow!("Invalid baseAsset: {} (use USD or EUR)", other)),
}
} else {
permission_json["baseAssetType"].as_u64().unwrap_or(0) as u8
};

let value_limit = permission_json["valueLimit"].as_u64().ok_or_else(|| {
anyhow!("valueLimit is required for oracle permission (u64 in base asset units)")
})?;

let passthrough_check = permission_json["passthrough"].as_bool().unwrap_or(false);

let recurring = if let Some(recurring) = permission_json.get("recurring") {
let window = recurring["window"].as_u64().ok_or_else(|| {
anyhow!("recurring.window is required when recurring is provided")
})?;
Some(swig_sdk::RecurringConfig::new(window))
} else {
None
};

Ok(Permission::OracleLimit {
base_asset_type,
value_limit,
passthrough_check,
recurring,
})
},
Some(unknown) => Err(anyhow!("Invalid permission type: {}", unknown)),
None => Err(anyhow!("Permission type is required")),
}
Expand Down Expand Up @@ -883,6 +922,12 @@ pub fn run_command_mode(ctx: &mut SwigCliContext, cmd: Command) -> Result<()> {
amount: 0,
recurring: None,
}),
"OracleLimit" | "Oracle" => Ok(Permission::OracleLimit {
base_asset_type: 0,
value_limit: 0,
passthrough_check: false,
recurring: None,
}),
"Program" => Ok(Permission::Program {
program_id: Pubkey::default(),
}),
Expand Down
55 changes: 52 additions & 3 deletions cli/src/interactive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -763,10 +763,11 @@ fn switch_authority_interactive(ctx: &mut SwigCliContext) -> Result<()> {
// Store the authority keypair in the context
ctx.authority = Some(authority.insecure_clone());

let authority_static: &Keypair = Box::leak(Box::new(authority.insecure_clone()));
ctx.wallet
.as_mut()
.unwrap()
.switch_authority(role_id, client_role, None)?;
.switch_authority(role_id, client_role, Some(authority_static))?;
Ok(())
}

Expand Down Expand Up @@ -794,7 +795,7 @@ fn transfer_interactive(ctx: &mut SwigCliContext) -> Result<()> {
.interact_text()?;

let transfer_instruction = transfer(
&ctx.wallet.as_ref().unwrap().get_swig_account()?,
&ctx.wallet.as_ref().unwrap().get_swig_wallet_address()?,
&Pubkey::from_str(&recipient)?,
amount,
);
Expand All @@ -803,7 +804,7 @@ fn transfer_interactive(ctx: &mut SwigCliContext) -> Result<()> {
.wallet
.as_mut()
.unwrap()
.sign(vec![transfer_instruction], None)?;
.sign_v2(vec![transfer_instruction], None)?;

println!("Signature: {}", signature);

Expand Down Expand Up @@ -855,6 +856,7 @@ pub fn get_permissions_interactive() -> Result<Vec<Permission>> {
"Sub Account (Sub-account management)",
"Stake (Stake management permissions)",
"Stake All (All stake management permissions)",
"Oracle (Value-based limit using price oracle)",
];

let mut permissions = Vec::new();
Expand Down Expand Up @@ -1069,6 +1071,53 @@ pub fn get_permissions_interactive() -> Result<Vec<Permission>> {
recurring: None,
},
13 => Permission::StakeAll,
14 => {
// Oracle value-based limit
// Choose base asset
let base_assets = vec!["USD (6 decimals)", "EUR (6 decimals)"];
let base_idx = Select::with_theme(&ColorfulTheme::default())
.with_prompt("Choose base asset for oracle limit")
.items(&base_assets)
.default(0)
.interact()?;
let base_asset_type: u8 = match base_idx {
0 => 0,
1 => 1,
_ => 0,
};

// Value limit in base asset minor units (e.g., 6 decimals for USD)
let value_limit: u64 = Input::with_theme(&ColorfulTheme::default())
.with_prompt("Enter value limit in base asset minor units (e.g., 100_000_000 for 100.000000)")
.interact_text()?;

let passthrough_check = Confirm::with_theme(&ColorfulTheme::default())
.with_prompt("Enable passthrough check (continue checking other actions)?")
.default(false)
.interact()?;

// Recurring?
let is_recurring = Confirm::with_theme(&ColorfulTheme::default())
.with_prompt("Make this a recurring oracle limit?")
.default(false)
.interact()?;

let recurring = if is_recurring {
let window: u64 = Input::with_theme(&ColorfulTheme::default())
.with_prompt("Enter time window in slots")
.interact_text()?;
Some(RecurringConfig::new(window))
} else {
None
};

Permission::OracleLimit {
base_asset_type,
value_limit,
passthrough_check,
recurring,
}
},
_ => unreachable!(),
};

Expand Down
Loading
Loading