-
Notifications
You must be signed in to change notification settings - Fork 67
An example contract for Solana #72
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
Merged
Merged
Changes from 11 commits
Commits
Show all changes
70 commits
Select commit
Hold shift + click to select a range
957f735
Add example contract for solana
yhzhang0128 8aed7a0
Add scripts for invocation in examples/sol-contract
yhzhang0128 0677a3e
Add readme in examples/sol-contract
yhzhang0128 1b9a91e
Add overflow checks in examples/sol-contract
yhzhang0128 685bffd
Cleanup and add comments in examples/sol-contract
yhzhang0128 b045b70
Remove hard-coded contract hash in examples/sol-contract
yhzhang0128 7432028
Improve comments wording in examples/sol-contract
yhzhang0128 d5f6d75
Update readme of examples/sol-contract
yhzhang0128 eba9da5
Remove some unnecessary dependencies in examples/sol-contract
yhzhang0128 aac5b9d
Remove the unwrap() in the code of examples/sol-contract
yhzhang0128 d0b28d9
Fix a grammar error
yhzhang0128 8ff6ee1
Succeed in adding state.rs and an initialization instruction
yhzhang0128 004b136
Cleanup
yhzhang0128 39d8300
Cleanup
yhzhang0128 32692b8
Cleanup
yhzhang0128 30ef43f
Add confidence interval
yhzhang0128 7235d20
Minor
yhzhang0128 d026e35
Minor
yhzhang0128 715de4d
Cleanup the contract
yhzhang0128 017030b
Cleanup the client-side code
yhzhang0128 9458fc0
Cleanup the contract code
yhzhang0128 ed7791e
Update readme
yhzhang0128 59dff00
Minor
yhzhang0128 829d38b
Minor
yhzhang0128 6d580bc
Add package-lock.json
yhzhang0128 eb7462b
Some renaming
yhzhang0128 9d86e9f
Hardcode loan/collateral quantity in Loan2Value instruction
yhzhang0128 0bdb6c1
Make loan_qty and collateral_qty parameters of instruction
yhzhang0128 bca85ae
Minor
yhzhang0128 6f4a4c0
Update dependency requirements for Solana related dependencies (#75)
dadepo 37604d2
Update the price schema (#76)
ali-behjati 4b7008c
Add example contract for solana
yhzhang0128 3a03ac3
Add scripts for invocation in examples/sol-contract
yhzhang0128 33c8afa
Add readme in examples/sol-contract
yhzhang0128 969b8ff
Add overflow checks in examples/sol-contract
yhzhang0128 81a4442
Cleanup and add comments in examples/sol-contract
yhzhang0128 ae47349
Remove hard-coded contract hash in examples/sol-contract
yhzhang0128 dc4d163
Improve comments wording in examples/sol-contract
yhzhang0128 908a3bc
Update readme of examples/sol-contract
yhzhang0128 d2ccf1a
Remove some unnecessary dependencies in examples/sol-contract
yhzhang0128 b718bb5
Remove the unwrap() in the code of examples/sol-contract
yhzhang0128 063f20a
Fix a grammar error
yhzhang0128 a6f9473
Succeed in adding state.rs and an initialization instruction
yhzhang0128 8f3f76d
Cleanup
yhzhang0128 e9911f7
Cleanup
yhzhang0128 0c62d7f
Cleanup
yhzhang0128 8ceb10d
Add confidence interval
yhzhang0128 0ffe5d5
Minor
yhzhang0128 633f266
Minor
yhzhang0128 a695622
Cleanup the contract
yhzhang0128 5e6d075
Cleanup the client-side code
yhzhang0128 5093ca1
Cleanup the contract code
yhzhang0128 38867b6
Update readme
yhzhang0128 26ed735
Minor
yhzhang0128 3406cff
Minor
yhzhang0128 b185b2c
Add package-lock.json
yhzhang0128 cb1451b
Some renaming
yhzhang0128 558dd0c
Hardcode loan/collateral quantity in Loan2Value instruction
yhzhang0128 e0d03b7
Make loan_qty and collateral_qty parameters of instruction
yhzhang0128 cb4bbcc
Minor
yhzhang0128 ebbaa16
Merge branch 'example-rs' of github.com:yhzhang0128/pyth-sdk-rs into …
yhzhang0128 87fe21f
Change solana version to 1.10.40, same as the Pyth SDK
yhzhang0128 834aa3d
Only use i64 to calculate the values, before normalizing with exponents
yhzhang0128 3cc600f
Normalize the values with the exponents
yhzhang0128 ef46095
Use borsh library for state serialize/deserialize
yhzhang0128 833a3fc
Resolve a few minor issues, such as renaming, from Ali's comments
yhzhang0128 9fc162d
Add more check in the Init instruction
yhzhang0128 6045e74
Fix a bug in client
yhzhang0128 ba7217a
Update the sol-contract example readme
yhzhang0128 9195001
Minor in readme
yhzhang0128 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,4 +6,5 @@ members = [ | |
| "pyth-sdk-solana/test-contract", | ||
| "pyth-sdk-cw", | ||
| "examples/cw-contract", | ||
| "examples/sol-contract" | ||
| ] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| build/example_sol_contract.so | ||
| build/example_sol_contract-keypair.json | ||
| scripts/invoke.js | ||
| scripts/invoke.js.map | ||
| scripts/node_modules/ | ||
| scripts/package-lock.json | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| [package] | ||
| name = "example-sol-contract" | ||
| version = "0.1.0" | ||
| authors = ["Pyth Data Foundation"] | ||
| edition = "2021" | ||
|
|
||
| [lib] | ||
| crate-type = ["cdylib", "lib"] | ||
|
|
||
| [dependencies] | ||
| borsh = "0.9" | ||
| pyth-sdk-solana = "0.5.0" | ||
yhzhang0128 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| solana-program = "1.8.1, < 1.11" | ||
|
|
||
| [dev-dependencies] | ||
| solana-sdk = "1.8.1, < 1.11" | ||
| solana-client = "1.8.1, < 1.11" | ||
| solana-program-test = "1.8.1, < 1.11" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Pyth SDK Example Contract for Solana | ||
|
|
||
| This repository contains a simple example demonstrating how to read the Pyth price from the Pyth contract on Solana. | ||
|
|
||
| The key functionality of this contract is in the `Loan2Value` function in `src/processor.rs`. | ||
| This function compares the value of some loan and some collateral, which is important in many lending protocols. | ||
yhzhang0128 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| An example invocation of this contract on the Solana devnet can be found in `scripts/invoke.ts`. | ||
|
|
||
| We assume that you have installed `cargo`, `solana`, `solana-keygen`, `npm` and `node`. | ||
|
|
||
yhzhang0128 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ## Usage | ||
|
|
||
| ```shell | ||
| > cd examples/sol-contract | ||
| # To build the example contract | ||
| > scripts/build.sh | ||
| # To deploy the example contract | ||
| > scripts/deploy.sh | ||
yhzhang0128 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # To invoke the example contract | ||
| > scripts/invoke.ts | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| This directory holds the output of build-bpf. See scripts/build.sh. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| cargo build-bpf --sbf-out-dir ./build |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| solana program deploy --program-id build/example_sol_contract-keypair.json build/example_sol_contract.so | ||
yhzhang0128 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| cd scripts; npm install typescript; npm run build; node invoke.js `solana-keygen pubkey ../build/example_sol_contract-keypair.json` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| const web3 = require("@solana/web3.js"); | ||
| const {struct, u8} = require("@solana/buffer-layout"); | ||
|
|
||
| export const invoke = async (loan: string, collateral: string) => { | ||
| /* Airdrop */ | ||
| console.log("Airdroping..."); | ||
yhzhang0128 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| let payer = web3.Keypair.generate(); | ||
| let keypair = web3.Keypair.generate(); | ||
| let conn = new web3.Connection(web3.clusterApiUrl('devnet')); | ||
| let airdropSig = await conn.requestAirdrop( | ||
| payer.publicKey, | ||
| web3.LAMPORTS_PER_SOL, | ||
| ); | ||
| await conn.confirmTransaction(airdropSig); | ||
|
|
||
| /* Specify accounts being touched */ | ||
| const loanKey = new web3.PublicKey(loan); | ||
| const collateralKey = new web3.PublicKey(collateral); | ||
| let keys = [{pubkey: loanKey, isSigner: false, isWritable: false}, | ||
| {pubkey: collateralKey, isSigner: false, isWritable: false}, | ||
| {pubkey: keypair.publicKey, isSigner: true, isWritable: false}]; | ||
|
|
||
| /* Prepare parameters */ | ||
| let allocateStruct = { | ||
| index: 0, // Loan2Value is instruction #0 in the program | ||
| layout: struct([ | ||
| u8('instruction'), | ||
| ]) | ||
| }; | ||
| let data = Buffer.alloc(allocateStruct.layout.span); | ||
| let layoutFields = Object.assign({instruction: allocateStruct.index}); | ||
| allocateStruct.layout.encode(layoutFields, data); | ||
|
|
||
| /* Invoke transaction */ | ||
| let tx = new web3.Transaction({ | ||
| feePayer: payer.publicKey | ||
| }); | ||
| let contract = process.argv[2]; | ||
| console.log("Invoking contract " + contract + "..."); | ||
| tx.add(new web3.TransactionInstruction({ | ||
| keys, | ||
| programId: contract, | ||
| data | ||
| })); | ||
|
|
||
| let txSig = await web3.sendAndConfirmTransaction(conn, tx, [payer, keypair]); | ||
| console.log("Confirmed TxHash " + txSig); | ||
| } | ||
|
|
||
| let ethToUSD = "EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw"; | ||
| let usdtToUSD = "38xoQ4oeJCBrcVvca2cGk7iV1dAfrmTR1kmhSCJQ8Jto"; | ||
| invoke(ethToUSD, usdtToUSD); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| { | ||
| "name": "scripts", | ||
| "version": "1.0.0", | ||
| "description": "", | ||
| "main": "invoke.js", | ||
| "scripts": { | ||
| "build": "npx tsc" | ||
| }, | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "ISC", | ||
| "devDependencies": { | ||
| "typescript": "^4.8.3" | ||
| }, | ||
| "dependencies": { | ||
| "@solana/web3.js": "^1.56.2" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "compilerOptions": { | ||
| "module": "commonjs", | ||
| "esModuleInterop": true, | ||
| "target": "es6", | ||
| "moduleResolution": "node", | ||
| "sourceMap": true | ||
| }, | ||
| "lib": ["es2015"] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //! Program entrypoint | ||
|
|
||
| use solana_program::entrypoint; | ||
| use solana_program::pubkey::Pubkey; | ||
| use solana_program::account_info::AccountInfo; | ||
| use solana_program::entrypoint::ProgramResult; | ||
|
|
||
| // Every solana program has an entry point function with 3 parameters: | ||
| // the program ID, the accounts being touched by this program, | ||
| // and an arbitrary byte array as the input data for execution. | ||
| entrypoint!(process_instruction); | ||
| fn process_instruction( | ||
| program_id: &Pubkey, | ||
| accounts: &[AccountInfo], | ||
| instruction_data: &[u8], | ||
| ) -> ProgramResult { | ||
| crate::processor::process_instruction( | ||
| program_id, accounts, instruction_data | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| //! Program instructions | ||
|
|
||
| use borsh::BorshSerialize; | ||
| use borsh::BorshDeserialize; | ||
|
|
||
| // A solana program contains a number of instructions. | ||
| // And this example contract contains only one instruction. | ||
| #[derive(Clone, Debug, BorshSerialize, BorshDeserialize, PartialEq)] | ||
| pub enum PythClientInstruction { | ||
| Loan2Value {}, // In this enum, Loan2Value is number 0. | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| // This is the file being compiled to the bpf shared object (.so). | ||
| // It specifies the 3 modules of this example contract. | ||
| pub mod processor; | ||
| pub mod entrypoint; | ||
| pub mod instruction; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| //! Program instruction processor | ||
|
|
||
| use solana_program::msg; | ||
| use solana_program::pubkey::Pubkey; | ||
| use solana_program::account_info::AccountInfo; | ||
| use solana_program::entrypoint::ProgramResult; | ||
| use solana_program::program_error::ProgramError; | ||
|
|
||
| use borsh::BorshDeserialize; | ||
| use crate::instruction::PythClientInstruction; | ||
| use pyth_sdk_solana::load_price_feed_from_account_info; | ||
|
|
||
| pub fn process_instruction( | ||
| _program_id: &Pubkey, | ||
yhzhang0128 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| _accounts: &[AccountInfo], | ||
| input: &[u8], | ||
| ) -> ProgramResult { | ||
| // Checking the validity of parameters is important. | ||
| // This important step is skipped in this example contract. | ||
yhzhang0128 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| let instruction = PythClientInstruction::try_from_slice(input)?; | ||
| match instruction { | ||
| PythClientInstruction::Loan2Value {} => { | ||
| let loan = &_accounts[0]; | ||
| let collateral = &_accounts[1]; | ||
| msg!("The loan key is {}.", loan.key); | ||
| msg!("The collateral key is {}.", collateral.key); | ||
| msg!("Assume 1 unit of loan and 3000 unit of collateral."); | ||
| let loan_cnt = 1; | ||
| let collateral_cnt = 3000; | ||
yhzhang0128 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // Calculate the value of the loan. | ||
| // Pyth is called to get the unit price of the loan. | ||
| let loan_value; | ||
| let feed1 = load_price_feed_from_account_info(loan)?; | ||
| let result1 = feed1.get_current_price().ok_or(ProgramError::Custom(0))?; | ||
| if let Some(v) = result1.price.checked_mul(loan_cnt) { | ||
yhzhang0128 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| loan_value = v; | ||
| } else { | ||
| // An overflow occurs for result1.price * loan_cnt. | ||
| return Err(ProgramError::Custom(1)) | ||
| } | ||
|
|
||
| // Calculate the value of the collateral. | ||
| // Pyth is called to get the unit price of the collateral. | ||
| let collateral_value; | ||
| let feed2 = load_price_feed_from_account_info(collateral)?; | ||
| let result2 = feed2.get_current_price().ok_or(ProgramError::Custom(0))?; | ||
| if let Some(v) = result2.price.checked_mul(collateral_cnt) { | ||
| collateral_value = v; | ||
| } else { | ||
| // An overflow occurs for result2.price * collateral_cnt. | ||
| return Err(ProgramError::Custom(1)) | ||
| } | ||
|
|
||
| // Check whether the value of the collateral is higher. | ||
yhzhang0128 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if collateral_value > loan_value { | ||
| msg!("Loan unit price is {}.", result1.price); | ||
| msg!("Collateral unit price is {}.", result2.price); | ||
| msg!("The value of collateral is higher."); | ||
| return Ok(()) | ||
| } else { | ||
| msg!("The value of loan is higher!"); | ||
| return Err(ProgramError::Custom(2)) | ||
| } | ||
| } | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.