Skip to content

Commit 739b786

Browse files
authored
Mercurial/pools/new sdk (#136)
* Mercurial new SDK version * Add compute budget program
1 parent f966b23 commit 739b786

File tree

17 files changed

+1738
-77
lines changed

17 files changed

+1738
-77
lines changed

components/instructions/instructionCard.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,15 @@ export default function InstructionCard({
6767
).then((d) => setDescriptor(d));
6868

6969
const getAmountImg = async () => {
70-
const sourcePk = proposalInstruction.account.getSingleInstruction()
71-
.accounts[0].pubkey;
70+
const ix = proposalInstruction.account.getSingleInstruction();
71+
72+
// Handle the specific case where there are no account in the instruction
73+
// like the ComputeBudgetProgram.requestUnits instruction
74+
if (ix.accounts.length === 0) {
75+
return;
76+
}
77+
78+
const sourcePk = ix.accounts[0].pubkey;
7279
const tokenAccount = await tryGetTokenAccount(
7380
connection.current,
7481
sourcePk,
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// The ComputeBudgetProgram.requestUnits function
2+
// is available starting at @solana/web3.js v1.41.0 and it's not possible for now
3+
// to update the main solana/web3.js package as it requires to update also governance related package
4+
// @ts-ignore
5+
import { ComputeBudgetProgram } from '@solana/web3.js-1.41.0';
6+
import { AccountMetaData } from '@solana/spl-governance';
7+
import { Connection } from '@solana/web3.js';
8+
import { u32, u8, struct } from 'buffer-layout';
9+
10+
export const COMPUTE_BUDGET_INSTRUCTIONS = {
11+
[ComputeBudgetProgram.programId]: {
12+
0: {
13+
name: 'Request Units',
14+
accounts: [],
15+
getDataUI: (
16+
_connection: Connection,
17+
data: Uint8Array,
18+
_accounts: AccountMetaData[],
19+
) => {
20+
const dataLayout = struct([
21+
u8('instruction'),
22+
u32('requestedUnits'),
23+
u32('additionalFee'),
24+
]);
25+
26+
const { requestedUnits, additionalFee } = dataLayout.decode(
27+
Buffer.from(data),
28+
) as any;
29+
30+
return (
31+
<div className="flex flex-col">
32+
<div>
33+
<span>Requested Units:</span>
34+
<span>{Number(requestedUnits).toLocaleString()}</span>
35+
</div>
36+
37+
<div>
38+
<span>Additional Fee:</span>
39+
<span>{Number(additionalFee).toLocaleString()}</span>
40+
</div>
41+
</div>
42+
);
43+
},
44+
},
45+
},
46+
};
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
import { AccountMetaData } from '@solana/spl-governance';
2+
import { Connection } from '@solana/web3.js';
3+
import { ANCHOR_DISCRIMINATOR_LAYOUT } from '@utils/helpers';
4+
import { struct, u8, nu64 } from 'buffer-layout';
5+
import { MercurialConfiguration } from '@tools/sdk/mercurial/configuration';
6+
import { tryGetMint, tryGetTokenMint } from '@utils/tokens';
7+
import { getSplTokenNameByMint } from '@utils/splTokens';
8+
import { nativeBNToUiAmount } from '@tools/sdk/units';
9+
import { BN } from '@blockworks-foundation/mango-client';
10+
11+
export const MERCURIAL_PROGRAM_INSTRUCTIONS = {
12+
[MercurialConfiguration.poolProgram.toBase58()]: {
13+
[MercurialConfiguration.instructionsCode.addImbalanceLiquidity]: {
14+
name: 'Mercurial - Add Imbalance Liquidity',
15+
accounts: [
16+
'Pool',
17+
'LP Mint',
18+
'User Pool LP',
19+
'A Vault LP',
20+
'B Vault LP',
21+
'A Vault',
22+
'B Vault',
23+
'A Vault LP Mint',
24+
'B Vault LP Mint',
25+
'A Token Vault',
26+
'B Token Vault',
27+
'User A Token',
28+
'User B Token',
29+
'User',
30+
'Vault Program',
31+
'Token Program',
32+
],
33+
getDataUI: async (
34+
connection: Connection,
35+
data: Uint8Array,
36+
accounts: AccountMetaData[],
37+
) => {
38+
const lpMint = accounts[1].pubkey;
39+
const userAToken = accounts[11].pubkey;
40+
const userBToken = accounts[12].pubkey;
41+
42+
const dataLayout = struct([
43+
u8('instruction'),
44+
...ANCHOR_DISCRIMINATOR_LAYOUT,
45+
nu64('minimumPoolTokenAmount'),
46+
nu64('tokenAAmount'),
47+
nu64('tokenBAmount'),
48+
]);
49+
50+
const {
51+
minimumPoolTokenAmount,
52+
tokenAAmount,
53+
tokenBAmount,
54+
} = dataLayout.decode(Buffer.from(data)) as any;
55+
56+
const [lpTokenInfo, tokenAInfo, tokenBInfo] = await Promise.all([
57+
tryGetMint(connection, lpMint),
58+
tryGetTokenMint(connection, userAToken),
59+
tryGetTokenMint(connection, userBToken),
60+
]);
61+
62+
if (!lpTokenInfo || !tokenAInfo || !tokenBInfo) {
63+
throw new Error('Cannot load mint info');
64+
}
65+
66+
const tokenAName = getSplTokenNameByMint(tokenAInfo.publicKey);
67+
const tokenBName = getSplTokenNameByMint(tokenBInfo.publicKey);
68+
69+
const uiMinimumPoolTokenAmount = nativeBNToUiAmount(
70+
new BN(minimumPoolTokenAmount),
71+
lpTokenInfo.account.decimals,
72+
);
73+
const uiTokenAAmount = nativeBNToUiAmount(
74+
new BN(tokenAAmount),
75+
tokenAInfo.account.decimals,
76+
);
77+
const uiTokenBAmount = nativeBNToUiAmount(
78+
new BN(tokenBAmount),
79+
tokenBInfo.account.decimals,
80+
);
81+
82+
return (
83+
<>
84+
<p>
85+
Pool {tokenAName} - {tokenBName}
86+
</p>
87+
<p>
88+
{`Minimum Pool Token Amount: ${Number(
89+
uiMinimumPoolTokenAmount.toString(),
90+
).toLocaleString()}`}
91+
</p>
92+
<p>
93+
{`Token A Amount: ${Number(
94+
uiTokenAAmount.toString(),
95+
).toLocaleString()}`}
96+
</p>
97+
<p>
98+
{`Token B Amount: ${Number(
99+
uiTokenBAmount.toString(),
100+
).toLocaleString()}`}
101+
</p>
102+
</>
103+
);
104+
},
105+
},
106+
[MercurialConfiguration.instructionsCode.removeBalanceLiquidity]: {
107+
name: 'Mercurial - Remove Balance Liquidity',
108+
accounts: [
109+
'Pool',
110+
'LP Mint',
111+
'User Pool LP',
112+
'A Vault LP',
113+
'B Vault LP',
114+
'A Vault',
115+
'B Vault',
116+
'A Vault LP Mint',
117+
'B Vault LP Mint',
118+
'A Token Vault',
119+
'B Token Vault',
120+
'User A Token',
121+
'User B Token',
122+
'User',
123+
'Vault Program',
124+
'Token Program',
125+
],
126+
getDataUI: async (
127+
connection: Connection,
128+
data: Uint8Array,
129+
accounts: AccountMetaData[],
130+
) => {
131+
const lpMint = accounts[1].pubkey;
132+
const userAToken = accounts[11].pubkey;
133+
const userBToken = accounts[12].pubkey;
134+
135+
const dataLayout = struct([
136+
u8('instruction'),
137+
...ANCHOR_DISCRIMINATOR_LAYOUT,
138+
nu64('poolTokenAmount'),
139+
nu64('minimumATokenOut'),
140+
nu64('minimumBTokenOut'),
141+
]);
142+
143+
const {
144+
poolTokenAmount,
145+
minimumATokenOut,
146+
minimumBTokenOut,
147+
} = dataLayout.decode(Buffer.from(data)) as any;
148+
149+
const [lpTokenInfo, tokenAInfo, tokenBInfo] = await Promise.all([
150+
tryGetMint(connection, lpMint),
151+
tryGetTokenMint(connection, userAToken),
152+
tryGetTokenMint(connection, userBToken),
153+
]);
154+
155+
if (!lpTokenInfo || !tokenAInfo || !tokenBInfo) {
156+
throw new Error('Cannot load mint info');
157+
}
158+
159+
const tokenAName = getSplTokenNameByMint(tokenAInfo.publicKey);
160+
const tokenBName = getSplTokenNameByMint(tokenBInfo.publicKey);
161+
162+
const uiPoolTokenAmount = nativeBNToUiAmount(
163+
new BN(poolTokenAmount),
164+
lpTokenInfo.account.decimals,
165+
);
166+
const uiMinimumATokenOut = nativeBNToUiAmount(
167+
new BN(minimumATokenOut),
168+
tokenAInfo.account.decimals,
169+
);
170+
const uiMinimumBTokenOut = nativeBNToUiAmount(
171+
new BN(minimumBTokenOut),
172+
tokenBInfo.account.decimals,
173+
);
174+
175+
return (
176+
<>
177+
<p>
178+
Pool {tokenAName} - {tokenBName}
179+
</p>
180+
<p>
181+
{`Pool Token Amount: ${Number(
182+
uiPoolTokenAmount.toString(),
183+
).toLocaleString()}`}
184+
</p>
185+
<p>
186+
{`Minimum Token A Amount Out: ${Number(
187+
uiMinimumATokenOut.toString(),
188+
).toLocaleString()}`}
189+
</p>
190+
<p>
191+
{`Minimum Token B Amount Out: ${Number(
192+
uiMinimumBTokenOut.toString(),
193+
).toLocaleString()}`}
194+
</p>
195+
</>
196+
);
197+
},
198+
},
199+
},
200+
};

components/instructions/tools.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import { MAPLE_FINANCE_PROGRAM_INSTRUCTIONS } from './programs/mapleFinance';
2929
import { FRIKTION_PROGRAM_INSTRUCTIONS } from './programs/friktion';
3030
import { DELTAFI_PROGRAM_INSTRUCTIONS } from './programs/deltafi';
3131
import { ORCA_PROGRAM_INSTRUCTIONS } from './programs/orca';
32+
import { COMPUTE_BUDGET_INSTRUCTIONS } from './programs/computeBudgetProgram';
33+
import { MERCURIAL_PROGRAM_INSTRUCTIONS } from './programs/mercurial';
34+
3235
/**
3336
* Default governance program id instance
3437
*/
@@ -132,6 +135,8 @@ export const INSTRUCTION_DESCRIPTORS = {
132135
...FRIKTION_PROGRAM_INSTRUCTIONS,
133136
...DELTAFI_PROGRAM_INSTRUCTIONS,
134137
...ORCA_PROGRAM_INSTRUCTIONS,
138+
...COMPUTE_BUDGET_INSTRUCTIONS,
139+
...MERCURIAL_PROGRAM_INSTRUCTIONS,
135140
};
136141

137142
export async function getInstructionDescriptor(

hooks/useGovernanceAssets.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ export default function useGovernanceAssets() {
225225
name: 'Orca',
226226
image: '/img/orca.svg',
227227
},
228+
[PackageEnum.Mercurial]: {
229+
name: 'Mercurial',
230+
image: '/img/mercurial.png',
231+
},
228232
};
229233

230234
const instructions: Instructions = {
@@ -659,6 +663,24 @@ export default function useGovernanceAssets() {
659663
packageId: PackageEnum.Orca,
660664
tag: 'beta',
661665
},
666+
[InstructionEnum.MercurialPoolDeposit]: {
667+
name: 'Mercurial Pool Deposit',
668+
isVisible: canUseAnyInstruction,
669+
packageId: PackageEnum.Mercurial,
670+
tag: 'beta',
671+
},
672+
[InstructionEnum.MercurialPoolWithdraw]: {
673+
name: 'Mercurial Pool Withdraw',
674+
isVisible: canUseAnyInstruction,
675+
packageId: PackageEnum.Mercurial,
676+
tag: 'beta',
677+
},
678+
[InstructionEnum.NativeIncreaseComputingBudget]: {
679+
name: 'Increase Computing Budget',
680+
isVisible: canUseAnyInstruction,
681+
packageId: PackageEnum.Native,
682+
tag: 'beta',
683+
},
662684
};
663685

664686
const availableInstructions = Object.entries(instructions)

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"@headlessui/react": "^1.4.2",
3333
"@heroicons/react": "^1.0.1",
3434
"@marinade.finance/marinade-ts-sdk": "^2.0.9",
35+
"@mercurial-finance/dynamic-amm-sdk": "0.0.1-769fc61d.0",
3536
"@metaplex-foundation/mpl-core": "^0.6.0",
3637
"@metaplex-foundation/mpl-token-metadata": "1.2.5",
3738
"@next/bundle-analyzer": "^12.1.0",
@@ -51,12 +52,13 @@
5152
"@soceanfi/descending-auction": "^0.2.1",
5253
"@solana/buffer-layout": "^4.0.0",
5354
"@solana/spl-governance": "0.0.34",
54-
"@solana/spl-token": "^0.1.3",
55+
"@solana/spl-token": "0.1.8",
5556
"@solana/spl-token-registry": "^0.2.4574",
5657
"@solana/wallet-adapter-base": "^0.7.1",
5758
"@solana/wallet-adapter-phantom": "^0.7.0",
5859
"@solana/wallet-adapter-sollet": "^0.8.0",
5960
"@solana/web3.js": "^1.34.0",
61+
"@solana/web3.js-1.41.0": "npm:@solana/[email protected]",
6062
"@solendprotocol/solend-sdk": "^0.4.9",
6163
"@tippyjs/react": "^4.2.5",
6264
"@uxd-protocol/uxd-client": "2.0.1",

0 commit comments

Comments
 (0)