@@ -49,7 +49,7 @@ import {
4949 withdrawExact ,
5050 liquidateObligationAndRedeemReserveCollateral ,
5151} from "../instructions" ;
52- import { NULL_ORACLE , POSITION_LIMIT } from "./constants" ;
52+ import { FEE_RECEIVER_AUTHORITY , NULL_ORACLE , POSITION_LIMIT } from "./constants" ;
5353import { EnvironmentType } from "./types" ;
5454import { getProgramId , U64_MAX , WAD } from "./constants" ;
5555import { PriceServiceConnection } from "@pythnetwork/price-service-client" ;
@@ -58,7 +58,6 @@ import {
5858 loadLookupTables ,
5959 PullFeed ,
6060 ON_DEMAND_MAINNET_PID ,
61- CrossbarClient ,
6261} from "@switchboard-xyz/on-demand" ;
6362import {
6463 createDepositAndMintWrapperTokensInstruction ,
@@ -114,35 +113,37 @@ type SupportType =
114113 | "wrapRepay"
115114 | "wsol" ;
116115
117- const ACTION_SUPPORT_REQUIREMENTS : {
118- [ Property in ActionType ] : Array < SupportType > ;
119- } = {
120- deposit : [ "wsol" , "wrap" , "createObligation" , "cAta" ] ,
121- borrow : [ "wsol" , "ata" , "refreshReserves" , "refreshObligation" , "unwrap" ] ,
122- withdraw : [
123- "wsol" ,
124- "ata" ,
125- "cAta" ,
126- "refreshReserves" ,
127- "refreshObligation" ,
128- "unwrap" ,
129- ] ,
130- repay : [ "wsol" , "wrap" ] ,
131- mint : [ "wsol" , "wrap" , "cAta" ] ,
132- redeem : [ "wsol" , "ata" , "refreshReserve" , "unwrap" ] ,
133- depositCollateral : [ "createObligation" ] ,
134- withdrawCollateral : [ "cAta" , "refreshReserves" , "refreshObligation" ] ,
135- forgive : [ "refreshReserves" , "refreshObligation" ] ,
136- liquidate : [
137- "wsol" ,
138- "ata" ,
139- "cAta" ,
140- "wrapRepay" ,
141- "unwrap" ,
142- "refreshReserves" ,
143- "refreshObligation" ,
144- ] ,
145- } ;
116+ function getSupportRequirementsForAction ( action : ActionType , hasBorrows : boolean ) : Array < SupportType > {
117+ const actionSupportRequirements : { [ Property in ActionType ] : Array < SupportType > } = {
118+ deposit : [ "wsol" , "wrap" , "createObligation" , "cAta" ] ,
119+ borrow : [ "wsol" , "ata" , "refreshReserves" , "refreshObligation" , "unwrap" ] ,
120+ withdraw : [
121+ "wsol" ,
122+ "ata" ,
123+ "cAta" ,
124+ hasBorrows ? "refreshReserves" : undefined ,
125+ hasBorrows ? "refreshObligation" : undefined ,
126+ "unwrap" ,
127+ ] . filter ( ( support ) => support !== undefined ) as Array < SupportType > ,
128+ repay : [ "wsol" , "wrap" ] ,
129+ mint : [ "wsol" , "wrap" , "cAta" ] ,
130+ redeem : [ "wsol" , "ata" , hasBorrows ? "refreshReserve" : undefined , "unwrap" ] . filter ( ( support ) => support !== undefined ) as Array < SupportType > ,
131+ depositCollateral : [ "createObligation" ] ,
132+ withdrawCollateral : [ "cAta" , hasBorrows ? "refreshReserves" : undefined , hasBorrows ? "refreshObligation" : undefined ] . filter ( ( support ) => support !== undefined ) as Array < SupportType > ,
133+ forgive : [ "refreshReserves" , "refreshObligation" ] ,
134+ liquidate : [
135+ "wsol" ,
136+ "ata" ,
137+ "cAta" ,
138+ "wrapRepay" ,
139+ "unwrap" ,
140+ "refreshReserves" ,
141+ "refreshObligation" ,
142+ ] ,
143+ } ;
144+
145+ return actionSupportRequirements [ action ] ;
146+ }
146147
147148export const toHexString = ( byteArray : number [ ] ) => {
148149 return (
@@ -187,6 +188,8 @@ export type InstructionWithSigners = {
187188 signers ?: Array < Signer > ;
188189 lookupTableAccounts ?: AddressLookupTableAccount [ ] ;
189190 computeUnits : number ;
191+ groupIndex ?: number ;
192+ index0 ?: boolean ;
190193} ;
191194
192195export const createDepositAndMintWrapperTokensInstructionComputeUnits = 55_154 ;
@@ -669,7 +672,7 @@ export class SolendActionCore {
669672 ) ;
670673
671674 await axn . addSupportIxs ( "withdrawCollateral" ) ;
672- await axn . addWithdrawIx ( ) ;
675+ await axn . addWithdrawObligationCollateralIx ( ) ;
673676
674677 return axn ;
675678 }
@@ -970,7 +973,7 @@ export class SolendActionCore {
970973 this . publicKey , // transferAuthority
971974 this . programId
972975 ) ,
973- computeUnits : 44_207
976+ computeUnits : 100_000
974977 }
975978 ) ;
976979 }
@@ -1018,9 +1021,9 @@ export class SolendActionCore {
10181021 ) ;
10191022 }
10201023
1021- addBorrowIx ( ) {
1024+ async addBorrowIx ( ) {
10221025 if ( this . debug ) console . log ( "adding borrow ix to lending txn" ) ;
1023- if ( this . hostAta && this . hostPublicKey ) {
1026+ if ( this . hostAta && this . hostPublicKey && ( this . hostPublicKey . toBase58 ( ) !== this . publicKey . toBase58 ( ) ) ) {
10241027 this . preTxnIxs . push (
10251028 {
10261029 instruction : createAssociatedTokenAccountIdempotentInstruction (
@@ -1033,6 +1036,20 @@ export class SolendActionCore {
10331036 }
10341037 ) ;
10351038 }
1039+ const liquidityFeeReceiverAccount = await this . connection . getAccountInfo ( new PublicKey ( this . reserve . liquidityFeeReceiverAddress ) ) ;
1040+ if ( ! liquidityFeeReceiverAccount ) {
1041+ this . preTxnIxs . push (
1042+ {
1043+ instruction : createAssociatedTokenAccountIdempotentInstruction (
1044+ this . publicKey ,
1045+ new PublicKey ( this . reserve . liquidityFeeReceiverAddress ) ,
1046+ FEE_RECEIVER_AUTHORITY ,
1047+ new PublicKey ( this . reserve . mintAddress )
1048+ ) ,
1049+ computeUnits : 21_845
1050+ }
1051+ ) ;
1052+ }
10361053 this . lendingIxs . push (
10371054 {
10381055 lookupTableAccounts : this . lookupTableAccount ? [ this . lookupTableAccount ] : undefined ,
@@ -1163,7 +1180,7 @@ export class SolendActionCore {
11631180 }
11641181
11651182 async addSupportIxs ( action : ActionType ) {
1166- const supports = ACTION_SUPPORT_REQUIREMENTS [ action ] ;
1183+ const supports = getSupportRequirementsForAction ( action , this . borrowReserves . length > 0 ) ;
11671184
11681185 for ( const support of supports ) {
11691186 switch ( support ) {
@@ -1244,9 +1261,9 @@ export class SolendActionCore {
12441261 {
12451262 instruction : createAssociatedTokenAccountIdempotentInstruction (
12461263 this . publicKey ,
1247- this . wrappedAta ,
1248- this . publicKey ,
1249- this . token2022Mint ,
1264+ this . wrappedAta ,
1265+ this . publicKey ,
1266+ this . token2022Mint ,
12501267 TOKEN_2022_PROGRAM_ID
12511268 ) ,
12521269 computeUnits : createAssociatedTokenAccountIdempotentInstructionComputeUnits
@@ -1296,13 +1313,14 @@ export class SolendActionCore {
12961313 }
12971314
12981315 static async buildPullPriceIxsStatic (
1299- oracleKeys : Array < string > ,
1316+ unfilteredOracleKeys : Array < string > ,
13001317 connection : Connection ,
13011318 wallet : SaveWallet ,
13021319 computeUnitPriceMicroLamports ?: number ,
13031320 environment ?: EnvironmentType ,
13041321 debug ?: boolean ,
13051322 ) {
1323+ const oracleKeys = unfilteredOracleKeys . filter ( k => k !== 'nu11111111111111111111111111111111111111111' && k !== '11111111111111111111111111111111' ) ;
13061324 let oracleIxs : InstructionWithSigners [ ] = [ ] ;
13071325 let pullPriceTxns : VersionedTransaction [ ] = [ ] ;
13081326 let pythIxGroups : Array < Array < InstructionWithSigners > > = [ ] ;
@@ -1313,10 +1331,10 @@ export class SolendActionCore {
13131331 units : 1_000_000 ,
13141332 } ) ;
13151333
1316- const oracleAccounts = await connection . getMultipleAccountsInfo (
1334+ const oracleAccounts = ( await connection . getMultipleAccountsInfo (
13171335 oracleKeys . map ( ( o ) => new PublicKey ( o ) ) ,
13181336 "processed"
1319- ) ;
1337+ ) ) ;
13201338
13211339 const provider = new AnchorProvider ( connection , {
13221340 publicKey : wallet . publicKey ,
@@ -1327,7 +1345,6 @@ export class SolendActionCore {
13271345
13281346 if ( environment === "production" || environment === "beta" ) {
13291347 const sbod = new Program ( idl , provider ) ;
1330- console . log ( oracleAccounts ) ;
13311348 const sbPulledOracles = oracleKeys . filter (
13321349 ( _o , index ) =>
13331350 oracleAccounts [ index ] ?. owner . toBase58 ( ) === sbod . programId . toBase58 ( )
@@ -1351,61 +1368,63 @@ export class SolendActionCore {
13511368 1
13521369 ) ;
13531370
1354- const res = sbPulledOracles . reduce ( ( acc , _curr , i ) => {
1371+ const res = feedAccounts . reduce ( ( acc , _curr , i ) => {
13551372 if ( ! ( i % 3 ) ) {
13561373 // if index is 0 or can be divided by the `size`...
1357- acc . push ( sbPulledOracles . slice ( i , i + 3 ) ) ; // ..push a chunk of the original array to the accumulator
1374+ acc . push ( feedAccounts . slice ( i , i + 3 ) ) ; // ..push a chunk of the original array to the accumulator
13581375 }
13591376 return acc ;
1360- } , [ ] as string [ ] [ ] ) ;
1377+ } , [ ] as PullFeed [ ] [ ] ) ;
1378+
1379+ const signatureInstructionIdxRaw =
1380+ typeof localStorage !== "undefined"
1381+ ? localStorage . getItem ( "signatureInstructionIdx" )
1382+ : null ;
1383+ const signatureInstructionIdx = signatureInstructionIdxRaw
1384+ ? parseInt ( signatureInstructionIdxRaw )
1385+ : undefined ;
13611386
1362- const crossbar = new CrossbarClient ( CROSSBAR_URL2 ) ;
13631387 await Promise . all (
1364- res . map ( async ( oracleGroup ) => {
1365- const [ ix , accountLookups , responses ] =
1388+ res . map ( async ( feedAccountGroup , groupIndex ) => {
1389+ const gateway = await feedAccountGroup [ 0 ] . fetchGatewayUrl ( ) ;
1390+ const [ ix , accountLookups ] =
13661391 await PullFeed . fetchUpdateManyIx ( sbod as any , {
1367- feeds : oracleGroup . map ( ( p ) => new PublicKey ( p ) ) ,
1368- crossbarClient : crossbar ,
1369-
1370- numSignatures,
1371- } ) ;
1372-
1373- // responses?.oracle_responses.forEach((response) => {
1374- // response?.errors.forEach((error) => {
1375- // if (error) {
1376- // console.error(error);
1377- // }
1378- // });
1379- // });
1380-
1381- console . log ( 'updated' ) ;
1392+ chain : "solana" ,
1393+ network : "mainnet-beta" ,
1394+ feeds : feedAccountGroup ,
1395+ numSignatures,
1396+ gateway,
1397+ signatureInstructionIdx,
1398+ } ,
1399+ ) ;
13821400
13831401 const lookupTables = ( await loadLookupTables ( feedAccounts ) ) . concat (
13841402 accountLookups
13851403 ) ;
13861404
1387- const instructions = [ priorityFeeIx , modifyComputeUnits , ix ] ;
1405+ const instructions = [ priorityFeeIx , modifyComputeUnits , ... ix ] ;
13881406
1389- // Get the latest context
13901407 const {
13911408 value : { blockhash } ,
13921409 } = await connection . getLatestBlockhashAndContext ( ) ;
13931410
1394- // Get Transaction Message
13951411 const message = new TransactionMessage ( {
13961412 payerKey : wallet . publicKey ,
13971413 recentBlockhash : blockhash ,
13981414 instructions,
13991415 } ) . compileToV0Message ( lookupTables ) ;
14001416
1401- // Get Versioned Transaction
14021417 const vtx = new VersionedTransaction ( message ) ;
14031418
14041419 if ( debug ) console . log ( "adding sbod ix to pullPriceTxns" ) ;
1405- oracleIxs . push ( {
1406- instruction : ix ,
1407- lookupTableAccounts : lookupTables ,
1408- computeUnits : 400_000 + sbPulledOracles . length * 100_000 ,
1420+ ix . forEach ( ( ixn , index ) => {
1421+ oracleIxs . push ( {
1422+ instruction : ixn ,
1423+ lookupTableAccounts : lookupTables ,
1424+ computeUnits : index === 0 ? 400_000 + sbPulledOracles . length * 100_000 : 10_000 ,
1425+ groupIndex,
1426+ index0 : true
1427+ } ) ;
14091428 } ) ;
14101429 pullPriceTxns . push ( vtx ) ;
14111430 } )
@@ -1458,8 +1477,8 @@ export class SolendActionCore {
14581477 priceFeedId : string ;
14591478 } >
14601479 )
1461- . sort ( ( a , b ) => a . key - b . key )
1462- . map ( ( x ) => x . priceFeedId ) ;
1480+ . sort ( ( a , b ) => a . key - b . key )
1481+ . map ( ( x ) => x . priceFeedId ) ;
14631482
14641483 if ( shuffledPriceIds . length ) {
14651484 if ( debug ) console . log ( "Feed accounts" , shuffledPriceIds ) ;
@@ -1472,39 +1491,33 @@ export class SolendActionCore {
14721491 0 // shardId of 0
14731492 ) ;
14741493
1475- transactionBuilder . addInstructions ( [
1476- { instruction : priorityFeeIx , signers : [ ] } ,
1477- { instruction : modifyComputeUnits , signers : [ ] } ,
1478- ] ) ;
1479-
14801494 const transactionsWithSigners =
14811495 await transactionBuilder . buildVersionedTransactions ( { } ) ;
14821496
1483- for ( const transaction of transactionsWithSigners ) {
1497+ for ( const [ index , transaction ] of transactionsWithSigners . entries ( ) ) {
14841498 const signers = transaction . signers ;
14851499 const tx = transaction . tx ;
14861500 const lookupTables = await Promise . all ( tx . message . addressTableLookups . map ( ( lookup ) => connection . getAddressLookupTable ( lookup . accountKey ) ) ) ;
14871501
14881502 if ( signers ) {
14891503 tx . sign ( signers ) ;
14901504 }
1491- pythIxGroups . push ( transactionBuilder . transactionInstructions . flatMap ( ( ixs , index1 ) => ixs . instructions . map (
1505+ pythIxGroups . push ( transactionBuilder . transactionInstructions [ index ] . instructions . map (
14921506 ( ix , index2 ) => {
14931507 let computeUnits = 0 ;
1494- if ( index1 === 0 && index2 === 0 ) {
1508+ if ( index2 === 0 ) {
14951509 computeUnits = 355_787 ;
14961510 }
14971511 if ( ix . programId . toBase58 ( ) === 'pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT' ) {
14981512 computeUnits = 43825 ;
14991513 }
1500-
15011514 return ( {
15021515 instruction : ix ,
1503- signers : ixs . signers ,
1516+ signers : transactionBuilder . transactionInstructions [ index ] . signers ,
15041517 lookupTables : lookupTables ,
15051518 computeUnits,
15061519 } ) }
1507- ) ) ) ;
1520+ ) ) ;
15081521 pullPriceTxns . push ( tx ) ;
15091522 }
15101523 console . log (
0 commit comments