-
Notifications
You must be signed in to change notification settings - Fork 238
sdk: fix helius-laserstream detection and prebuild:browser hook #2199
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
base: master
Are you sure you want to change the base?
Changes from all commits
63eccde
3569e33
2cbc109
a811db6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1319,12 +1319,13 @@ pub fn handle_transfer_pools<'c: 'info, 'info>( | |
| "cant transfer between the same pool" | ||
| )?; | ||
|
|
||
| let mut remaining_accounts_iter = ctx.remaining_accounts.iter().peekable(); | ||
| let AccountMaps { | ||
| perp_market_map, | ||
| spot_market_map, | ||
| mut oracle_map, | ||
| } = load_maps( | ||
| &mut ctx.remaining_accounts.iter().peekable(), | ||
| &mut remaining_accounts_iter, | ||
|
Comment on lines
+1322
to
+1328
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dual hook transfers can fail due to shared draining iterator.
Please split/segment remaining accounts per transfer invocation (or change consumption semantics so each call reads only its own required extras). Also applies to: 1698-1702, 1731-1735 🤖 Prompt for AI Agents |
||
| &MarketSet::new(), | ||
| &get_writable_spot_market_set_from_many(vec![ | ||
| deposit_from_market_index, | ||
|
|
@@ -1686,7 +1687,6 @@ pub fn handle_transfer_pools<'c: 'info, 'info>( | |
| .find(|acc| acc.key() == spot_market_mint.key()) | ||
| .map(|acc| InterfaceAccount::try_from(acc).unwrap()); | ||
|
|
||
| // TODO: support transfer hook tokens | ||
| controller::token::send_from_program_vault( | ||
| token_program, | ||
| &ctx.accounts.deposit_from_spot_market_vault, | ||
|
|
@@ -1695,7 +1695,11 @@ pub fn handle_transfer_pools<'c: 'info, 'info>( | |
| state.signer_nonce, | ||
| deposit_transfer, | ||
| &mint_account_info, | ||
| None, | ||
| if deposit_from_spot_market.has_transfer_hook() { | ||
| Some(&mut remaining_accounts_iter) | ||
| } else { | ||
| None | ||
| }, | ||
| )?; | ||
| } | ||
|
|
||
|
|
@@ -1716,7 +1720,6 @@ pub fn handle_transfer_pools<'c: 'info, 'info>( | |
| .find(|acc| acc.key() == spot_market_mint.key()) | ||
| .map(|acc| InterfaceAccount::try_from(acc).unwrap()); | ||
|
|
||
| // TODO: support transfer hook tokens | ||
| controller::token::send_from_program_vault( | ||
| token_program, | ||
| &ctx.accounts.borrow_to_spot_market_vault, | ||
|
|
@@ -1725,7 +1728,11 @@ pub fn handle_transfer_pools<'c: 'info, 'info>( | |
| state.signer_nonce, | ||
| borrow_transfer, | ||
| &mint_account_info, | ||
| None, | ||
| if borrow_to_spot_market.has_transfer_hook() { | ||
| Some(&mut remaining_accounts_iter) | ||
| } else { | ||
| None | ||
| }, | ||
| )?; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -15,7 +15,9 @@ | |||||
| "build": "yarn clean && tsc -p tsconfig.json && tsc -p tsconfig.browser.json && node scripts/postbuild.js", | ||||||
| "build:browser": "yarn clean && tsc -p tsconfig.json && tsc -p tsconfig.browser.json && node scripts/postbuild.js --force-env browser", | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: The 🔧 Proposed fix to invoke prebuild:browser-"build:browser": "yarn clean && tsc -p tsconfig.json && tsc -p tsconfig.browser.json && node scripts/postbuild.js --force-env browser",
+"build:browser": "yarn prebuild:browser && yarn clean && tsc -p tsconfig.json && tsc -p tsconfig.browser.json && node scripts/postbuild.js --force-env browser",📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| "build:minify": "node build-browser.js", | ||||||
| "clean": "rm -rf lib", | ||||||
| "prebuild": "node scripts/mock-optional-deps.js", | ||||||
| "prebuild:browser": "node scripts/mock-optional-deps.js", | ||||||
| "clean": "node -e \"const fs = require('fs'); fs.rmSync('lib', { recursive: true, force: true })\"", | ||||||
| "test": "mocha -r ts-node/register tests/**/*.ts --ignore 'tests/dlob/**/*.ts'", | ||||||
| "test:match": "mocha -r ts-node/register --ignore 'tests/dlob/**/*.ts'", | ||||||
| "test:inspect": "mocha --inspect-brk -r ts-node/register tests/**/*.ts", | ||||||
|
|
@@ -104,7 +106,7 @@ | |||||
| }, | ||||||
| "description": "SDK for Drift Protocol", | ||||||
| "engines": { | ||||||
| "node": "^24.0.0" | ||||||
| "node": ">=18.0.0" | ||||||
| }, | ||||||
| "resolutions": { | ||||||
| "@solana/web3.js": "1.98.0", | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
|
|
||
| const targetDir = path.join(__dirname, '..', 'node_modules', 'helius-laserstream'); | ||
|
|
||
| let packageResolvable = false; | ||
| try { | ||
| require.resolve('helius-laserstream'); | ||
| packageResolvable = true; | ||
| } catch (_) { | ||
| // not installed or not resolvable | ||
| } | ||
|
|
||
| if (!packageResolvable) { | ||
| console.log('helius-laserstream is not installed. Creating a local shim for compilation...'); | ||
| try { | ||
| fs.mkdirSync(targetDir, { recursive: true }); | ||
| } catch (e) { | ||
| console.error('Failed to create directory for helius-laserstream shim:', e); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| const packageJson = { | ||
| name: 'helius-laserstream', | ||
| version: '0.1.8', | ||
| main: 'index.js', | ||
| types: 'index.d.ts' | ||
| }; | ||
|
|
||
| const indexJs = `module.exports = { | ||
| CommitmentLevel: { | ||
| PROCESSED: 0, | ||
| CONFIRMED: 1, | ||
| FINALIZED: 2 | ||
| }, | ||
| CompressionAlgorithms: { | ||
| identity: 0, | ||
| deflate: 1, | ||
| gzip: 2, | ||
| zstd: 3 | ||
| }, | ||
| subscribe: () => { | ||
| throw new Error('helius-laserstream is shimmed and not available on this platform.'); | ||
| } | ||
| };`; | ||
|
|
||
| const indexDts = `export interface LaserstreamConfig { | ||
| apiKey?: string; | ||
| endpoint?: string; | ||
| maxReconnectAttempts?: number; | ||
| channelOptions?: any; | ||
| } | ||
| export interface SubscribeRequest { | ||
| slots?: any; | ||
| accounts?: any; | ||
| transactions?: any; | ||
| blocks?: any; | ||
| blocksMeta?: any; | ||
| accountsDataSlice?: any; | ||
| commitment?: any; | ||
| entry?: any; | ||
| transactionsStatus?: any; | ||
| } | ||
| export interface SubscribeUpdate { | ||
| account?: { | ||
| slot: string | number; | ||
| account: { | ||
| pubkey: string; | ||
| owner: string; | ||
| lamports: string | number; | ||
| data: Uint8Array | number[] | string; | ||
| executable: boolean; | ||
| rentEpoch: string | number; | ||
| }; | ||
| }; | ||
| } | ||
| export enum CommitmentLevel { | ||
| PROCESSED = 0, | ||
| CONFIRMED = 1, | ||
| FINALIZED = 2 | ||
| } | ||
| export enum CompressionAlgorithms { | ||
| identity = 0, | ||
| deflate = 1, | ||
| gzip = 2, | ||
| zstd = 3 | ||
| } | ||
| export function subscribe(...args: any[]): any;`; | ||
|
|
||
| try { | ||
| fs.writeFileSync(path.join(targetDir, 'package.json'), JSON.stringify(packageJson, null, 2)); | ||
| fs.writeFileSync(path.join(targetDir, 'index.js'), indexJs); | ||
| fs.writeFileSync(path.join(targetDir, 'index.d.ts'), indexDts); | ||
| console.log('Shim created successfully.'); | ||
| } catch (e) { | ||
| console.error('Failed to write files for helius-laserstream shim:', e); | ||
| process.exit(1); | ||
| } | ||
| } else { | ||
| console.log('helius-laserstream is already installed.'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shared transfer-hook iterator can break later CPIs in the same instruction.
A single
remaining_accounts_iteris reused across the whole function, but the transfer-hook path consumes iterator entries. Since this function can perform multiple hook-enabled transfers (inside the spot-position loop), the first hook CPI can drain accounts required by later hook CPIs and cause runtime failure.Use per-transfer account windows/iterators (or make hook-account consumption bounded to one transfer) instead of one shared draining iterator.
Also applies to: 3317-3321, 3339-3343
🤖 Prompt for AI Agents