From 4fca923155e110b1a3e9987d4ee92911e7043f68 Mon Sep 17 00:00:00 2001 From: Noah Prince <83885631+ChewingGlass@users.noreply.github.com> Date: Wed, 20 Aug 2025 09:46:34 -0700 Subject: [PATCH 01/10] Fix rewards recipient etl (#1048) * Fix rewards recipient etl * Better logic --- .../explodeRecipientDestinationOwnership.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/account-postgres-sink-service/src/plugins/explodeRecipientDestinationOwnership.ts b/packages/account-postgres-sink-service/src/plugins/explodeRecipientDestinationOwnership.ts index 3eb62ff98..4b0bc8998 100644 --- a/packages/account-postgres-sink-service/src/plugins/explodeRecipientDestinationOwnership.ts +++ b/packages/account-postgres-sink-service/src/plugins/explodeRecipientDestinationOwnership.ts @@ -36,17 +36,22 @@ export const ExplodeRecipientDestinationOwnershipPlugin = ((): IPlugin => { }) } - // Case 2: New destination is a mini fanout if (newDestination !== PublicKey.default.toBase58()) { + await RewardsRecipient.destroy({ + where: { + asset: account.asset, + }, + transaction + }) + + // Case 2: New destination is a mini fanout const newMiniFanout = await MiniFanout.findByPk(newDestination, { transaction }) if (newMiniFanout) { await handleMiniFanout(account.asset, newMiniFanout, transaction) return account } - } - - // Case 3: New destination is a direct recipient (not a mini fanout) - if (newDestination !== PublicKey.default.toBase58()) { + + // Case 3: New destination is a direct recipient (not a mini fanout) const kta = await KeyToAsset.findOne({ where: { dao: 'BQ3MCuTT5zVBhNfQ4SjMh3NPVhFy73MPV8rjfq5d1zie', @@ -55,7 +60,7 @@ export const ExplodeRecipientDestinationOwnershipPlugin = ((): IPlugin => { transaction }) - await RewardsRecipient.upsert({ + await RewardsRecipient.create({ asset: account.asset, owner: newDestination, destination: newDestination, From bfb21e18c82f9b10166299fc3714592e9465fe41 Mon Sep 17 00:00:00 2001 From: Noah Prince <83885631+ChewingGlass@users.noreply.github.com> Date: Wed, 20 Aug 2025 15:17:07 -0700 Subject: [PATCH 02/10] Fix bugs in dc auto topoff when deploying to devnet (#1051) --- packages/dc-auto-top-sdk/src/pdas.ts | 5 +- packages/helium-admin-cli/package.json | 1 + .../src/setup-dc-auto-topoff.ts | 212 ++++++++++++++++++ packages/helium-admin-cli/tsconfig.json | 3 + packages/helium-admin-cli/yarn.deploy.lock | 18 ++ .../initialize_auto_top_off_v0.rs | 2 +- .../src/instructions/schedule_task_v0.rs | 4 +- .../instructions/update_auto_top_off_v0.rs | 4 + programs/dc-auto-top/src/lib.rs | 2 +- programs/dc-auto-top/src/state.rs | 3 +- tests/dc-auto-topoff.ts | 2 +- yarn.lock | 3 +- 12 files changed, 248 insertions(+), 11 deletions(-) create mode 100644 packages/helium-admin-cli/src/setup-dc-auto-topoff.ts diff --git a/packages/dc-auto-top-sdk/src/pdas.ts b/packages/dc-auto-top-sdk/src/pdas.ts index 4b0c563e8..a733699b2 100644 --- a/packages/dc-auto-top-sdk/src/pdas.ts +++ b/packages/dc-auto-top-sdk/src/pdas.ts @@ -2,13 +2,12 @@ import { PublicKey } from "@solana/web3.js"; import { PROGRAM_ID } from "./constants"; export function autoTopOffKey( - dataCredits: PublicKey, - subDao: PublicKey, + delegatedDataCredits: PublicKey, authority: PublicKey, programId: PublicKey = PROGRAM_ID ): [PublicKey, number] { return PublicKey.findProgramAddressSync( - [Buffer.from("auto_top_off", "utf-8"), dataCredits.toBuffer(), subDao.toBuffer(), authority.toBuffer()], + [Buffer.from("auto_top_off", "utf-8"), delegatedDataCredits.toBuffer(), authority.toBuffer()], programId ) } diff --git a/packages/helium-admin-cli/package.json b/packages/helium-admin-cli/package.json index e284ad931..5b77bbac4 100644 --- a/packages/helium-admin-cli/package.json +++ b/packages/helium-admin-cli/package.json @@ -43,6 +43,7 @@ "@helium/circuit-breaker-sdk": "^0.10.35", "@helium/crypto": "^4.10.2", "@helium/data-credits-sdk": "^0.10.35", + "@helium/dc-auto-top-sdk": "^0.10.35", "@helium/distributor-oracle": "^0.10.35", "@helium/fanout-sdk": "^0.10.35", "@helium/helium-entity-manager-sdk": "^0.10.35", diff --git a/packages/helium-admin-cli/src/setup-dc-auto-topoff.ts b/packages/helium-admin-cli/src/setup-dc-auto-topoff.ts new file mode 100644 index 000000000..3ce9dd0eb --- /dev/null +++ b/packages/helium-admin-cli/src/setup-dc-auto-topoff.ts @@ -0,0 +1,212 @@ +import * as anchor from "@coral-xyz/anchor"; +import { dataCreditsKey, delegatedDataCreditsKey, init as initDc } from "@helium/data-credits-sdk"; +import { autoTopOffKey, init as initDcAutoTopoff, queueAuthorityKey } from "@helium/dc-auto-top-sdk"; +import { daoKey, subDaoKey } from "@helium/helium-sub-daos-sdk"; +import { TASK_QUEUE_ID } from "@helium/hpl-crons-sdk"; +import { DC_MINT, HNT_MINT, MOBILE_MINT } from "@helium/spl-utils"; +import { createAssociatedTokenAccountIdempotentInstruction, getAssociatedTokenAddressSync } from "@solana/spl-token"; +import { ComputeBudgetProgram, PublicKey, SystemProgram, TransactionInstruction } from "@solana/web3.js"; +import Squads from "@sqds/sdk"; +import os from "os"; +import yargs from "yargs/yargs"; +import { loadKeypair, sendInstructionsOrSquads } from "./utils"; +import { init as initTuktuk, nextAvailableTaskIds, taskKey, taskQueueAuthorityKey } from "@helium/tuktuk-sdk"; + +export async function run(args: any = process.argv) { + const yarg = yargs(args).options({ + wallet: { + alias: "k", + describe: "Anchor wallet keypair", + default: `${os.homedir()}/.config/solana/id.json`, + }, + url: { + alias: "u", + default: "http://127.0.0.1:8899", + describe: "The solana url", + }, + hntMint: { + type: "string", + describe: "Pubkey of the HNT token", + default: HNT_MINT.toBase58(), + }, + dcMint: { + type: "string", + describe: "Pubkey of the Data Credit token", + default: DC_MINT.toBase58(), + }, + threshold: { + type: "number", + describe: "Threshold for auto topoff in DC, raw with no decimals", + default: 1, + }, + initialLamports: { + type: "number", + describe: "Initial lamports to send to the auto topoff, pays for crank turns.", + default: 10000000, + }, + routerKey: { + type: "string", + describe: "The router key for the delegated data credits", + required: true, + }, + subDaoMint: { + type: "string", + describe: "The sub dao mint for the delegated data credits", + default: MOBILE_MINT.toBase58(), + }, + multisig: { + type: 'string', + describe: + 'Address of the squads multisig to be authority. If not provided, your wallet will be the authority', + }, + authorityIndex: { + type: 'number', + describe: 'Authority index for squads. Defaults to 1', + default: 1, + }, + schedule: { + type: 'string', + describe: 'Cron schedule for the auto topoff', + required: true, + }, + }); + + const argv = await yarg.argv; + process.env.ANCHOR_WALLET = argv.wallet; + process.env.ANCHOR_PROVIDER_URL = argv.url; + anchor.setProvider(anchor.AnchorProvider.local(argv.url)); + const hntMint = new PublicKey(HNT_MINT); + const subDaoMint = new PublicKey(argv.subDaoMint); + const subDao = subDaoKey(subDaoMint)[0]; + const dcMint = new PublicKey(argv.dcMint); + + + const provider = anchor.getProvider() as anchor.AnchorProvider; + const dataCreditsProgram = await initDc(provider); + const dcAutoTopoffProgram = await initDcAutoTopoff(provider); + const tuktukProgram = await initTuktuk(provider); + + const wallet = new anchor.Wallet(loadKeypair(argv.wallet)); + const squads = Squads.endpoint(process.env.ANCHOR_PROVIDER_URL, wallet, { + commitmentOrConfig: "finalized", + }); + let authority = provider.wallet.publicKey; + let multisig = argv.multisig ? new PublicKey(argv.multisig) : null; + if (multisig) { + authority = squads.getAuthorityPDA(multisig, argv.authorityIndex); + } + + const routerKey = argv.routerKey; + const delegatedDc = delegatedDataCreditsKey(subDao, routerKey)[0] + const instructions: TransactionInstruction[] = [] + const delegatedDcAcc = await dataCreditsProgram.account.delegatedDataCreditsV0.fetchNullable(delegatedDc) + if (!delegatedDcAcc) { + instructions.push( + createAssociatedTokenAccountIdempotentInstruction( + authority, + getAssociatedTokenAddressSync(dcMint, authority, true), + authority, + dcMint, + ), + await dataCreditsProgram.methods.delegateDataCreditsV0({ + routerKey, + amount: new anchor.BN(0), + }) + .accountsPartial({ + payer: authority, + subDao: subDao, + delegatedDataCredits: delegatedDc, + dcMint, + dao: daoKey(hntMint)[0], + fromAccount: getAssociatedTokenAddressSync(dcMint, authority, true), + dataCredits: dataCreditsKey(dcMint)[0], + }) + .instruction() + ) + } + + const autoTopOff = autoTopOffKey(delegatedDc, authority)[0] + + const taskQueue = await tuktukProgram.account.taskQueueV0.fetch(TASK_QUEUE_ID) + const [nextPythTask, nextTask] = nextAvailableTaskIds(taskQueue.taskBitmap, 2) + const autoTopOffAcc = await dcAutoTopoffProgram.account.autoTopOffV0.fetchNullable(autoTopOff!) + if (autoTopOffAcc) { + const queueAuthority = queueAuthorityKey()[0] + const updateIx = await dcAutoTopoffProgram.methods.updateAutoTopOffV0({ + newTaskId: nextTask, + newPythTaskId: nextPythTask, + schedule: argv.schedule, + threshold: new anchor.BN(argv.threshold), + }) + .accountsStrict({ + payer: authority, + autoTopOff: autoTopOff!, + nextTask: autoTopOffAcc.nextTask, + newTask: taskKey(TASK_QUEUE_ID, nextTask)[0], + newPythTask: taskKey(TASK_QUEUE_ID, nextPythTask)[0], + taskQueue: TASK_QUEUE_ID, + authority: authority, + systemProgram: SystemProgram.programId, + queueAuthority, + nextPythTask: autoTopOffAcc.nextPythTask, + taskQueueAuthority: taskQueueAuthorityKey(TASK_QUEUE_ID, queueAuthority)[0], + tuktukProgram: tuktukProgram.programId, + }) + .instruction() + instructions.push(updateIx) + } else { + const instruction = await dcAutoTopoffProgram.methods.initializeAutoTopOffV0({ + schedule: argv.schedule, + threshold: new anchor.BN(argv.threshold), + routerKey, + }) + .accountsPartial({ + payer: authority, + authority, + taskQueue: TASK_QUEUE_ID, + delegatedDataCredits: delegatedDc, + dao: daoKey(hntMint)[0], + dataCredits: dataCreditsKey(dcMint)[0], + dcMint, + hntMint, + subDao, + }) + .instruction() + + instructions.push(instruction) + const { instruction: scheduleTaskInstruction, pubkeys: { queueAuthority } } = await dcAutoTopoffProgram.methods.scheduleTaskV0({ + taskId: nextTask, + pythTaskId: nextPythTask, + }) + .accountsPartial({ + payer: authority, + autoTopOff: autoTopOff!, + nextTask: PublicKey.default, + task: taskKey(TASK_QUEUE_ID, nextTask)[0], + pythTask: taskKey(TASK_QUEUE_ID, nextPythTask)[0], + taskQueue: TASK_QUEUE_ID, + }) + .prepare() + console.log("Queue authority", queueAuthority!.toBase58()) + instructions.push(scheduleTaskInstruction) + + instructions.push( + SystemProgram.transfer({ + fromPubkey: authority, + toPubkey: autoTopOff!, + lamports: argv.initialLamports, + }) + ) + } + + await sendInstructionsOrSquads({ + provider, + instructions, + executeTransaction: false, + squads, + multisig: argv.multisig ? new PublicKey(argv.multisig) : undefined, + authorityIndex: argv.authorityIndex, + signers: [], + }); + console.log(`Initialized auto topoff for ${routerKey} with schedule ${argv.schedule} and threshold ${argv.threshold}. Send HNT to ${autoTopOff!.toBase58()}`); +} diff --git a/packages/helium-admin-cli/tsconfig.json b/packages/helium-admin-cli/tsconfig.json index bd27527a6..a6a702cc4 100644 --- a/packages/helium-admin-cli/tsconfig.json +++ b/packages/helium-admin-cli/tsconfig.json @@ -13,6 +13,9 @@ { "path": "../distributor-oracle" }, + { + "path": "../dc-auto-top-sdk" + }, { "path": "../mini-fanout-sdk" }, diff --git a/packages/helium-admin-cli/yarn.deploy.lock b/packages/helium-admin-cli/yarn.deploy.lock index eb01e2558..d884b376f 100644 --- a/packages/helium-admin-cli/yarn.deploy.lock +++ b/packages/helium-admin-cli/yarn.deploy.lock @@ -302,6 +302,23 @@ __metadata: languageName: unknown linkType: soft +"@helium/dc-auto-top-sdk@^0.10.35": + version: 0.0.0-use.local + resolution: "@helium/dc-auto-top-sdk@workspace:packages/dc-auto-top-sdk" + dependencies: + "@coral-xyz/anchor": ^0.31.0 + "@helium/anchor-resolvers": ^0.10.35 + "@helium/idls": ^0.10.35 + "@helium/spl-utils": ^0.10.35 + bn.js: ^5.2.0 + bs58: ^4.0.1 + git-format-staged: ^2.1.3 + ts-loader: ^9.2.3 + ts-node: ^10.9.1 + typescript: ^5.2.2 + languageName: unknown + linkType: soft + "@helium/distributor-oracle@^0.10.35": version: 0.0.0-use.local resolution: "@helium/distributor-oracle@workspace:packages/distributor-oracle" @@ -373,6 +390,7 @@ __metadata: "@helium/circuit-breaker-sdk": ^0.10.35 "@helium/crypto": ^4.10.2 "@helium/data-credits-sdk": ^0.10.35 + "@helium/dc-auto-top-sdk": ^0.10.35 "@helium/distributor-oracle": ^0.10.35 "@helium/fanout-sdk": ^0.10.35 "@helium/helium-entity-manager-sdk": ^0.10.35 diff --git a/programs/dc-auto-top/src/instructions/initialize_auto_top_off_v0.rs b/programs/dc-auto-top/src/instructions/initialize_auto_top_off_v0.rs index 182b73f41..4961a8902 100644 --- a/programs/dc-auto-top/src/instructions/initialize_auto_top_off_v0.rs +++ b/programs/dc-auto-top/src/instructions/initialize_auto_top_off_v0.rs @@ -32,7 +32,7 @@ pub struct InitializeAutoTopOffV0<'info> { init, payer = payer, space = AutoTopOffV0::size(&args), - seeds = [b"auto_top_off", data_credits.key().as_ref(), sub_dao.key().as_ref(), authority.key().as_ref()], + seeds = [b"auto_top_off", delegated_data_credits.key().as_ref(), authority.key().as_ref()], bump )] pub auto_top_off: Box>, diff --git a/programs/dc-auto-top/src/instructions/schedule_task_v0.rs b/programs/dc-auto-top/src/instructions/schedule_task_v0.rs index 2d2f0df2a..29d35d518 100644 --- a/programs/dc-auto-top/src/instructions/schedule_task_v0.rs +++ b/programs/dc-auto-top/src/instructions/schedule_task_v0.rs @@ -142,13 +142,13 @@ pub fn schedule_impl(ctx: &mut ScheduleTaskV0, args: ScheduleTaskArgsV0) -> Resu &[queue_authority_seeds!(auto_top_off)], ), QueueTaskArgsV0 { - trigger: TriggerV0::Timestamp(next_time - 1), + trigger: TriggerV0::Timestamp(next_time - 60), transaction: TransactionSourceV0::RemoteV0 { signer: TUKTUK_PYTH_SIGNER, url: format!("{}/{}", TUKTUK_PYTH_URL, auto_top_off.hnt_price_oracle), }, crank_reward: None, - free_tasks: 0, + free_tasks: 1, id: args.pyth_task_id, description: format!( "pyth dist {}", diff --git a/programs/dc-auto-top/src/instructions/update_auto_top_off_v0.rs b/programs/dc-auto-top/src/instructions/update_auto_top_off_v0.rs index b1ce85325..3369c789b 100644 --- a/programs/dc-auto-top/src/instructions/update_auto_top_off_v0.rs +++ b/programs/dc-auto-top/src/instructions/update_auto_top_off_v0.rs @@ -22,6 +22,7 @@ pub struct UpdateAutoTopOffArgsV0 { pub new_task_id: u16, pub new_pyth_task_id: u16, pub schedule: Option, + pub threshold: Option, } #[derive(Accounts)] @@ -73,6 +74,9 @@ pub fn handler(ctx: Context, args: UpdateAutoTopOffArgsV0) - })?; auto_top_off.schedule = schedule; } + if let Some(threshold) = args.threshold { + auto_top_off.threshold = threshold; + } resize_to_fit( &ctx.accounts.payer.to_account_info(), &ctx.accounts.system_program.to_account_info(), diff --git a/programs/dc-auto-top/src/lib.rs b/programs/dc-auto-top/src/lib.rs index 86d5f06c4..56f7350e7 100644 --- a/programs/dc-auto-top/src/lib.rs +++ b/programs/dc-auto-top/src/lib.rs @@ -31,7 +31,7 @@ security_txt! { pub mod dc_auto_top { use super::*; - pub fn schedule_task(ctx: Context, args: ScheduleTaskArgsV0) -> Result<()> { + pub fn schedule_task_v0(ctx: Context, args: ScheduleTaskArgsV0) -> Result<()> { instructions::schedule_task_v0::handler(ctx, args) } diff --git a/programs/dc-auto-top/src/state.rs b/programs/dc-auto-top/src/state.rs index 4ed317058..12c3e804e 100644 --- a/programs/dc-auto-top/src/state.rs +++ b/programs/dc-auto-top/src/state.rs @@ -29,8 +29,7 @@ macro_rules! auto_top_off_seeds { ( $auto_top_off:expr ) => { &[ b"auto_top_off".as_ref(), - $auto_top_off.data_credits.as_ref(), - $auto_top_off.sub_dao.as_ref(), + $auto_top_off.delegated_data_credits.as_ref(), $auto_top_off.authority.as_ref(), &[$auto_top_off.bump], ] diff --git a/tests/dc-auto-topoff.ts b/tests/dc-auto-topoff.ts index 31f7c39ca..9e0956313 100644 --- a/tests/dc-auto-topoff.ts +++ b/tests/dc-auto-topoff.ts @@ -201,7 +201,7 @@ describe("dc-auto-topoff", () => { lamports: 1000000000, })]); - await program.methods.scheduleTask({ + await program.methods.scheduleTaskV0({ taskId: nextTask, pythTaskId: nextPythTask, }) diff --git a/yarn.lock b/yarn.lock index 911f7e519..cea30d673 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1035,7 +1035,7 @@ __metadata: languageName: unknown linkType: soft -"@helium/dc-auto-top-sdk@workspace:packages/dc-auto-top-sdk": +"@helium/dc-auto-top-sdk@^0.10.35, @helium/dc-auto-top-sdk@workspace:packages/dc-auto-top-sdk": version: 0.0.0-use.local resolution: "@helium/dc-auto-top-sdk@workspace:packages/dc-auto-top-sdk" dependencies: @@ -1208,6 +1208,7 @@ __metadata: "@helium/circuit-breaker-sdk": ^0.10.35 "@helium/crypto": ^4.10.2 "@helium/data-credits-sdk": ^0.10.35 + "@helium/dc-auto-top-sdk": ^0.10.35 "@helium/distributor-oracle": ^0.10.35 "@helium/fanout-sdk": ^0.10.35 "@helium/helium-entity-manager-sdk": ^0.10.35 From d52386774b1f8b08a5fc46c2e5cd9c06797958bd Mon Sep 17 00:00:00 2001 From: Bryan Date: Tue, 26 Aug 2025 11:47:54 -0500 Subject: [PATCH 03/10] change hnt logo (#1052) --- packages/metadata-service/src/assets/hnt.png | Bin 44073 -> 11774 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/packages/metadata-service/src/assets/hnt.png b/packages/metadata-service/src/assets/hnt.png index f2a6ef09de971ad88d44241c975ce34b546fc087..4f3a751f8d1af91a9623c190ded5986f1892a11c 100644 GIT binary patch literal 11774 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 literal 44073 zcmagGcQ~8x7e9^=RO}+L6;-vVz0y*L%fwmUhnbD6Giqlg5=B1pS!w`OC7fEaDRdA{;OyU(TKSX zwvH6}r^fq7tm6%Xv_@H*DT8h_zi|Yd%rNQhohKH*BEH<*;GRFooZOT=nM<#6|B)pn zz8wjjK&c`d*c`-k_2z0;d|$AnxIHihIPjQ!wGZl#=c8N5$LnqR6&^c=+ z&DLoSFo;~K^Dzb$Xwp7$Vtv&%Z?f4CE0C>bu5(F7S)+%x+cQ7WP7$i+%9%Td9#XNt z#hlU(-)2q>%VKkG43MoM4|=MU1O1OoTAK2RIoi3eQc(5nZuU(so$l^-lH#%AOdY0%yrjav$npAEhZP&Mp6-A*&pnRPw{lSl!Iu@XZDGic|8kr)WtMLo_RY~V z`bu}9WaVa(6F_}RfaHIe08uGqHKg9b|~e%z6wLQO*JPvMBjzf%Mhh zuLA9RfFb~tF0B_y-I~P|@_fj1jY*h)j3|g%j`Ex$6QJL;Q@dGQyZAv!bn&915!-TpJLm3{$YZ!KFAERaHrxzzvbn9mM6 z+h}UMy4c;7IwSi$-gr5?3xa zYs(|qS&unt*%{Yv+F)F(?#Z-^YOlCW114ZqYBR@c%3hXnop)Op{P4Q_@AY5oL2AvIsTjrySCFTwdD5KJZXdoC#zD z&G}%Z!*60mWLG4@77)lBlsHWj&O4wo57{Eg^u2_+a+lh1>Z_8-)&0V9G`OOSSo?@p zri-)KQoiW|Dr8>4X;tlbw^?2s1g6XjROj^Uolkah`frhKH+UlzJ6)314$9*tAAv$Y z8zc_=bdWTZfLo6RQ8#M1aQO0Xoyb@3`t9D>0dP`gM()tneQAwbE1<7``CShJ&?WH` z*#1rR3NCA?sP1y=pg0a+(q59oO5xl^>$b{=rvxTAg3tf4Wd|NlHi@YnP|0+75(s7q z+y$SjzNP)%PXfNQ&D6Hr{~Nd;jtEC)!SyF#+e4h6#yiCo3Iqw%HpE%q;O)dqa!ytl z%*al54jzEqyLln5&p(m9=AaqH8ef!mngJTYK!Jy6z1-5K2t*ZkqY90T-x$iOY5uPF zt&9fOobX-ROzd~0@l*~{Q!Uq%FE|mAk_FD)ZeW|3_TODA4`i2P&!i0cur0q(oWL;i zyCP$P>)1GU^%f*Q906KC+ROIdMiOVf9!<1hXuBAz!8GrZZ++Y)59k-p{6%b8clM-22q z;>Dr@{j-C{?6$L06F|{11ov6z$uRD85XI^X*l{;;3Ut06Rr9u*mV&Eo;)$-x^!`wG zeB}rDP8Ak@9qET2PW{FlV|SWbIml?pX*z?s@MF$QPIKsDwn_)TL!F3;=o~D|^8S-WQ-f5m!Dr){LuX zlsm~W6&!Ifa+wJr5C*EyvmoDh(@)%xq()zVZAD$yYu0hEN_NNbD4a;3L2%(F^|E~i z6aT4{Eoj18HqD{wk6c6M(Jq1)jmii7NJ8((Px+m9(-sJJqp_f`!|a)L_2uLM{&>8t zjQ>*5htXh3f3VMUvom6FI5!hAP!9E0^O6r>GyuP^9O6Gwlc#S-0>EqjWD!X6W8i%Z znc%r?>k5?2r5$)_F^ND79hmwUcU9fL=*HHdy*n?AZu*NJcQB0)(+J(&x6^<`pgF6Y z0mlJ*9N4;TO}d$2wU_VsdTZkm91Ks435y#Vbx$$zfaQwB<3Gh-88tBeP-asi!R_F- z5e$eK3vB{`1|ap4S*7p`y!|8>!T^5tW#@(2--PD*S{rL_e#m+h0lmOKNdlhMxpFx@ z@(TgZFn^PQKzW~=)l{zeFC#5<{jVVrm)1_u-^yg!*PTM%%YgNE3MW?(+v1Q_l6Tmhh zFq2sj7v71p#Ot-xN)eQfqO9*%0Dyy}Ms1TEDS(hhUvXLf{W?L&bbJ71aOuB-P=n*Z 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�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 From b17d2990f5a2948dc2c45195d0c27d19fb6aef5f Mon Sep 17 00:00:00 2001 From: bry Date: Tue, 9 Sep 2025 19:48:44 -0500 Subject: [PATCH 04/10] docsite --- .../docsite/src/pages/docs/api/dc-auto-top-sdk.md | 3 ++- .../docsite/src/pages/docs/api/hexboosting-sdk.md | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/docsite/src/pages/docs/api/dc-auto-top-sdk.md b/packages/docsite/src/pages/docs/api/dc-auto-top-sdk.md index 62ad7d05d..3a7a851d0 100644 --- a/packages/docsite/src/pages/docs/api/dc-auto-top-sdk.md +++ b/packages/docsite/src/pages/docs/api/dc-auto-top-sdk.md @@ -58,7 +58,7 @@ If you are looking for a quick start guide, check out the [Getting Started](/doc | ---- | --------------- | ---- | | args | [object Object] | | -### schedule_task +### schedule_task_v0 #### Accounts @@ -422,6 +422,7 @@ undefined | new_task_id | u16 | | new_pyth_task_id | u16 | | schedule | string | +| threshold | u64 | ### WindowV0 diff --git a/packages/docsite/src/pages/docs/api/hexboosting-sdk.md b/packages/docsite/src/pages/docs/api/hexboosting-sdk.md index be8deb8d3..6ccb3ddfa 100644 --- a/packages/docsite/src/pages/docs/api/hexboosting-sdk.md +++ b/packages/docsite/src/pages/docs/api/hexboosting-sdk.md @@ -46,6 +46,21 @@ If you are looking for a quick start guide, check out the [Getting Started](/doc | Name | Type | Docs | | ---- | ---- | ---- | +### close_boost_v1 + +#### Accounts + +| Name | Mutability | Signer | Docs | +| ---------------------- | ---------- | ------ | ---- | +| rent_reclaim_authority | immut | no | | +| boost_config | immut | no | | +| boosted_hex | immut | no | | + +#### Args + +| Name | Type | Docs | +| ---- | ---- | ---- | + ### initialize_boost_config_v0 #### Accounts From 28b548abd1dc512622f2e01f84f1c0c40fe42b01 Mon Sep 17 00:00:00 2001 From: Noah Prince <83885631+ChewingGlass@users.noreply.github.com> Date: Wed, 10 Sep 2025 10:18:08 -0700 Subject: [PATCH 05/10] Fix migration service not signing (#1060) --- packages/migration-service/src/ledger.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/migration-service/src/ledger.ts b/packages/migration-service/src/ledger.ts index 65994d448..2da86af06 100644 --- a/packages/migration-service/src/ledger.ts +++ b/packages/migration-service/src/ledger.ts @@ -227,9 +227,9 @@ export async function getMigrateTransactions( const draft = transactions[i]; tx.serialize(); if ( - draft.signers?.some((sig) => - sig.publicKey.equals(provider.wallet.publicKey) - ) + draft.instructions.map((ix) => ix.keys).flat().some((key) => + key.pubkey.equals(provider.wallet.publicKey) && key.isSigner + ) || draft.feePayer?.equals(provider.wallet.publicKey) ) { return provider.wallet.signTransaction(tx); } From 2fd759c2c7212b58ae83b8e88b8b9d497eed4abc Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Wed, 10 Sep 2025 10:20:41 -0700 Subject: [PATCH 06/10] Bump node --- migration-docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migration-docker/Dockerfile b/migration-docker/Dockerfile index 3903a21f1..b07d3fb09 100644 --- a/migration-docker/Dockerfile +++ b/migration-docker/Dockerfile @@ -1,5 +1,5 @@ # Specify the base image -FROM node:18-alpine AS BUILD_IMAGE +FROM node:20-alpine AS BUILD_IMAGE WORKDIR /app @@ -17,7 +17,7 @@ RUN lerna bootstrap RUN yarn run build -FROM node:18-alpine +FROM node:20-alpine WORKDIR /app From d29e2e438cec83f73477092214083f4c7d13b245 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Wed, 10 Sep 2025 10:22:35 -0700 Subject: [PATCH 07/10] Bump node --- packages/migration-service/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/migration-service/Dockerfile b/packages/migration-service/Dockerfile index 5dfda322e..26272f0a9 100644 --- a/packages/migration-service/Dockerfile +++ b/packages/migration-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:20-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -12,7 +12,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build RUN npm prune --production -FROM node:18-alpine +FROM node:20-alpine WORKDIR /usr/src/app From 7fcd6dfd5a337cc19eb23e9cbfe1e80e91278a3b Mon Sep 17 00:00:00 2001 From: Noah Prince <83885631+ChewingGlass@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:25:44 -0500 Subject: [PATCH 08/10] Fix mini fanout system program mut issue (#1056) * Fix mini fanout system program mut issue * Fix second dist --- .../src/instructions/close_mini_fanout_v0.rs | 60 +++++++++++-------- .../src/instructions/distribute_v0.rs | 8 +-- .../instructions/initialize_mini_fanout_v0.rs | 4 +- .../src/instructions/schedule_task_v0.rs | 4 +- programs/mini-fanout/src/state.rs | 3 + 5 files changed, 46 insertions(+), 33 deletions(-) diff --git a/programs/mini-fanout/src/instructions/close_mini_fanout_v0.rs b/programs/mini-fanout/src/instructions/close_mini_fanout_v0.rs index 3df3a9dbb..142d8567c 100644 --- a/programs/mini-fanout/src/instructions/close_mini_fanout_v0.rs +++ b/programs/mini-fanout/src/instructions/close_mini_fanout_v0.rs @@ -9,7 +9,7 @@ use tuktuk_program::{ cpi::{accounts::DequeueTaskV0, dequeue_task_v0}, program::Tuktuk, }, - TaskQueueAuthorityV0, TaskV0, + TaskQueueAuthorityV0, }; use crate::{fanout_seeds, queue_authority_seeds, state::*}; @@ -51,7 +51,7 @@ pub struct CloseMiniFanoutV0<'info> { pub task_queue: UncheckedAccount<'info>, /// CHECK: current task account #[account(mut)] - pub next_task: Box>, + pub next_task: UncheckedAccount<'info>, #[account(mut)] pub token_account: Account<'info, TokenAccount>, #[account( @@ -63,7 +63,7 @@ pub struct CloseMiniFanoutV0<'info> { pub owner_token_account: Account<'info, TokenAccount>, /// CHECK: current pre-task account #[account(mut)] - pub next_pre_task: Box>, + pub next_pre_task: UncheckedAccount<'info>, /// CHECK: task rent refund account #[account(mut)] pub task_rent_refund: UncheckedAccount<'info>, @@ -95,27 +95,37 @@ pub fn handler(ctx: Context) -> Result<()> { }, &[fanout_seeds!(ctx.accounts.mini_fanout)], ))?; - dequeue_task_v0(CpiContext::new_with_signer( - ctx.accounts.tuktuk_program.to_account_info(), - DequeueTaskV0 { - task_queue: ctx.accounts.task_queue.to_account_info(), - task: ctx.accounts.next_task.to_account_info(), - queue_authority: ctx.accounts.queue_authority.to_account_info(), - rent_refund: ctx.accounts.task_rent_refund.to_account_info(), - task_queue_authority: ctx.accounts.task_queue_authority.to_account_info(), - }, - &[queue_authority_seeds!(ctx.accounts.mini_fanout)], - ))?; - dequeue_task_v0(CpiContext::new_with_signer( - ctx.accounts.tuktuk_program.to_account_info(), - DequeueTaskV0 { - task_queue: ctx.accounts.task_queue.to_account_info(), - task: ctx.accounts.next_pre_task.to_account_info(), - queue_authority: ctx.accounts.queue_authority.to_account_info(), - rent_refund: ctx.accounts.task_rent_refund.to_account_info(), - task_queue_authority: ctx.accounts.task_queue_authority.to_account_info(), - }, - &[queue_authority_seeds!(ctx.accounts.mini_fanout)], - ))?; + if ctx.accounts.next_task.key() != crate::ID + && ctx.accounts.next_task.key() != Pubkey::default() + && !ctx.accounts.next_task.data_is_empty() + { + dequeue_task_v0(CpiContext::new_with_signer( + ctx.accounts.tuktuk_program.to_account_info(), + DequeueTaskV0 { + task_queue: ctx.accounts.task_queue.to_account_info(), + task: ctx.accounts.next_task.to_account_info(), + queue_authority: ctx.accounts.queue_authority.to_account_info(), + rent_refund: ctx.accounts.task_rent_refund.to_account_info(), + task_queue_authority: ctx.accounts.task_queue_authority.to_account_info(), + }, + &[queue_authority_seeds!(ctx.accounts.mini_fanout)], + ))?; + } + if ctx.accounts.next_pre_task.key() != crate::ID + && ctx.accounts.next_pre_task.key() != Pubkey::default() + && !ctx.accounts.next_pre_task.data_is_empty() + { + dequeue_task_v0(CpiContext::new_with_signer( + ctx.accounts.tuktuk_program.to_account_info(), + DequeueTaskV0 { + task_queue: ctx.accounts.task_queue.to_account_info(), + task: ctx.accounts.next_pre_task.to_account_info(), + queue_authority: ctx.accounts.queue_authority.to_account_info(), + rent_refund: ctx.accounts.task_rent_refund.to_account_info(), + task_queue_authority: ctx.accounts.task_queue_authority.to_account_info(), + }, + &[queue_authority_seeds!(ctx.accounts.mini_fanout)], + ))?; + } Ok(()) } diff --git a/programs/mini-fanout/src/instructions/distribute_v0.rs b/programs/mini-fanout/src/instructions/distribute_v0.rs index a381f99e5..89b2553ed 100644 --- a/programs/mini-fanout/src/instructions/distribute_v0.rs +++ b/programs/mini-fanout/src/instructions/distribute_v0.rs @@ -28,7 +28,7 @@ pub struct DistributeV0<'info> { pub next_task: Box>, /// CHECK: Make sure this is empty, pre task needs to be run before task. #[account( - constraint = next_pre_task.data_is_empty() || next_pre_task.key() == Pubkey::default() @ ErrorCode::PreTaskNotRun + constraint = next_pre_task.data_is_empty() || next_pre_task.key() == crate::ID @ ErrorCode::PreTaskNotRun )] pub next_pre_task: UncheckedAccount<'info>, #[account(mut)] @@ -203,8 +203,8 @@ pub fn handler<'info>( .task_queue .add_lamports(ctx.accounts.task_queue.min_crank_reward * 2)?; } else { - mini_fanout.next_task = Pubkey::default(); - mini_fanout.next_pre_task = Pubkey::default(); + mini_fanout.next_task = crate::ID; + mini_fanout.next_pre_task = crate::ID; return Ok(RunTaskReturnV0 { tasks: vec![], accounts: vec![], @@ -221,7 +221,7 @@ pub fn handler<'info>( trigger: TriggerV0::Timestamp(next_time), transaction: TransactionSourceV0::CompiledV0(compiled_tx), crank_reward: None, - free_tasks: 0, + free_tasks: 2, description: format!("dist {}", &mini_fanout.key().to_string()[..(32 - 9)]), }]; if let Some(pre_task) = mini_fanout.pre_task.clone() { diff --git a/programs/mini-fanout/src/instructions/initialize_mini_fanout_v0.rs b/programs/mini-fanout/src/instructions/initialize_mini_fanout_v0.rs index e413b58d0..98a511c97 100644 --- a/programs/mini-fanout/src/instructions/initialize_mini_fanout_v0.rs +++ b/programs/mini-fanout/src/instructions/initialize_mini_fanout_v0.rs @@ -145,7 +145,7 @@ pub fn handler( task_queue: ctx.accounts.task_queue.key(), mint: ctx.accounts.mint.key(), token_account: ctx.accounts.token_account.key(), - next_task: Pubkey::default(), + next_task: crate::ID, rent_refund: ctx.accounts.payer.key(), bump: ctx.bumps.mini_fanout, schedule: args.schedule, @@ -161,7 +161,7 @@ pub fn handler( total_owed: 0, }) .collect(), - next_pre_task: Pubkey::default(), + next_pre_task: crate::ID, pre_task: args.pre_task, }); diff --git a/programs/mini-fanout/src/instructions/schedule_task_v0.rs b/programs/mini-fanout/src/instructions/schedule_task_v0.rs index 36527eb68..56be2e253 100644 --- a/programs/mini-fanout/src/instructions/schedule_task_v0.rs +++ b/programs/mini-fanout/src/instructions/schedule_task_v0.rs @@ -39,13 +39,13 @@ pub struct ScheduleTaskV0<'info> { /// CHECK: Via constraint /// Only allow one task to be scheduled at a time #[account( - constraint = next_task.data_is_empty() || next_task.key() == Pubkey::default() + constraint = next_task.data_is_empty() || next_task.key() == Pubkey::default() || next_task.key() == crate::ID )] pub next_task: UncheckedAccount<'info>, /// CHECK: Via constraint /// Only allow one task to be scheduled at a time #[account( - constraint = next_task.data_is_empty() || next_task.key() == Pubkey::default() + constraint = next_pre_task.data_is_empty() || next_pre_task.key() == Pubkey::default() || next_pre_task.key() == crate::ID )] pub next_pre_task: UncheckedAccount<'info>, /// CHECK: queue authority diff --git a/programs/mini-fanout/src/state.rs b/programs/mini-fanout/src/state.rs index 6abf550d7..d4f51b14a 100644 --- a/programs/mini-fanout/src/state.rs +++ b/programs/mini-fanout/src/state.rs @@ -20,6 +20,9 @@ pub struct MiniFanoutV0 { pub mint: Pubkey, pub token_account: Pubkey, pub task_queue: Pubkey, + // If next task is set to crate::ID, it means there's no next task. + // The reason we do this is because you can't set Pubkey::default() as mutable, + // which means on `close` you'd need conditional mutability logic, which plays horribly with idls. pub next_task: Pubkey, pub rent_refund: Pubkey, /// Bump seed for PDA derivation From 9d1170049f7eaca99f73b6469f17bd9f41eda7bb Mon Sep 17 00:00:00 2001 From: Noah Prince <83885631+ChewingGlass@users.noreply.github.com> Date: Wed, 17 Sep 2025 08:58:01 -0700 Subject: [PATCH 09/10] Use pyth ephermeral price updates to eliminate dependence on sponsored feeds (#1045) --- .../workflows/develop-release-program.yaml | 2 +- .github/workflows/docker-push.yaml | 2 +- .github/workflows/manual-devnet-deploy.yaml | 2 +- .github/workflows/npm-canary-release.yaml | 2 +- .github/workflows/npm-publish.yaml | 2 +- .github/workflows/release-program.yaml | 2 +- .github/workflows/tests.yaml | 2 +- Anchor.toml | 16 +- migration-docker/Dockerfile | 4 +- .../account-postgres-sink-service/Dockerfile | 4 +- packages/active-device-oracle/Dockerfile | 2 +- packages/asset-ownership-service/Dockerfile | 4 +- packages/crons/Dockerfile | 4 +- packages/crons/src/close-governance.ts | 31 +- packages/currency-utils/package.json | 2 + packages/currency-utils/src/currencyUtils.ts | 79 +- packages/currency-utils/src/pyth.ts | 1257 ----------------- packages/currency-utils/tsconfig.json | 3 + packages/currency-utils/yarn.deploy.lock | 671 ++++++++- packages/data-credits-sdk/package.json | 2 + .../src/functions/mintDataCredits.ts | 78 + packages/data-credits-sdk/src/index.ts | 3 +- packages/data-credits-sdk/yarn.deploy.lock | 470 +++++- packages/distributor-oracle/Dockerfile | 4 +- packages/entity-invalidator/Dockerfile | 4 +- packages/fanout-metadata-service/Dockerfile | 4 +- packages/faucet-service/Dockerfile | 4 +- packages/helium-admin-cli/src/create-dao.ts | 68 +- .../helium-admin-cli/src/create-subdao.ts | 70 +- packages/helium-admin-cli/src/mint-dc.ts | 39 +- .../src/update-data-credits.ts | 6 - packages/helium-admin-cli/yarn.deploy.lock | 398 +++++- packages/helium-vote-service/Dockerfile | 4 +- packages/metadata-service/Dockerfile | 4 +- packages/metadata-service/yarn.deploy.lock | 309 +++- packages/migration-service/Dockerfile | 4 +- packages/migration-service/yarn.deploy.lock | 400 +++++- packages/monitor-service/Dockerfile | 4 +- packages/monitor-service/yarn.deploy.lock | 465 +++++- .../Dockerfile | 4 +- .../rewards-oracle-faucet-service/Dockerfile | 4 +- packages/spl-utils/src/constants.ts | 2 + packages/spl-utils/src/transaction.ts | 9 +- packages/tokens-to-rent-service/Dockerfile | 4 +- packages/tuktuk-pyth-service/Dockerfile | 4 +- packages/vsr-metadata-service/Dockerfile | 4 +- .../initialize_data_credits_v0.rs | 3 - .../src/instructions/mint_data_credits_v0.rs | 7 +- .../instructions/update_data_credits_v0.rs | 8 +- .../src/instructions/top_off_v0.rs | 3 - .../onboard_data_only_mobile_hotspot_v0.rs | 2 +- .../src/instructions/queue_end_epoch.rs | 2 +- .../src/instructions/claim_welcome_pack_v0.rs | 4 +- tests/data-credits.ts | 63 +- tests/dc-auto-topoff.ts | 9 +- tests/distributor-oracle.ts | 11 +- tests/helium-entity-manager.ts | 65 +- tests/helium-sub-daos.ts | 27 +- tests/hexboosting.ts | 16 +- tests/utils/fixtures.ts | 3 - tests/welcome-pack.ts | 7 +- yarn.lock | 30 + 62 files changed, 3027 insertions(+), 1695 deletions(-) delete mode 100644 packages/currency-utils/src/pyth.ts create mode 100644 packages/data-credits-sdk/src/functions/mintDataCredits.ts diff --git a/.github/workflows/develop-release-program.yaml b/.github/workflows/develop-release-program.yaml index f9ca2cfad..ab36eb7f0 100644 --- a/.github/workflows/develop-release-program.yaml +++ b/.github/workflows/develop-release-program.yaml @@ -2,7 +2,7 @@ name: Deploy Programs to devnet env: SOLANA_CLI_VERSION: 2.1.6 - NODE_VERSION: 18.12.1 + NODE_VERSION: 22.19.0 on: push: diff --git a/.github/workflows/docker-push.yaml b/.github/workflows/docker-push.yaml index c698c9370..cc6cc8b86 100644 --- a/.github/workflows/docker-push.yaml +++ b/.github/workflows/docker-push.yaml @@ -2,7 +2,7 @@ name: Deploy to ECR env: SOLANA_CLI_VERSION: 2.1.6 - NODE_VERSION: 18.12.1 + NODE_VERSION: 22.19.0 on: push: diff --git a/.github/workflows/manual-devnet-deploy.yaml b/.github/workflows/manual-devnet-deploy.yaml index 1f16acca5..01ba9a17c 100644 --- a/.github/workflows/manual-devnet-deploy.yaml +++ b/.github/workflows/manual-devnet-deploy.yaml @@ -2,7 +2,7 @@ name: Manual Devnet Program Deploy env: SOLANA_CLI_VERSION: 2.1.6 - NODE_VERSION: 18.12.1 + NODE_VERSION: 22.19.0 on: workflow_dispatch: diff --git a/.github/workflows/npm-canary-release.yaml b/.github/workflows/npm-canary-release.yaml index b0caf9c20..3625d5cea 100644 --- a/.github/workflows/npm-canary-release.yaml +++ b/.github/workflows/npm-canary-release.yaml @@ -5,7 +5,7 @@ on: env: SOLANA_CLI_VERSION: 2.1.6 - NODE_VERSION: 18.12.1 + NODE_VERSION: 22.19.0 permissions: contents: read # for checkout diff --git a/.github/workflows/npm-publish.yaml b/.github/workflows/npm-publish.yaml index 8d1c3b806..63f7a8858 100644 --- a/.github/workflows/npm-publish.yaml +++ b/.github/workflows/npm-publish.yaml @@ -2,7 +2,7 @@ name: NPM Publish env: SOLANA_CLI_VERSION: 2.1.6 - NODE_VERSION: 18.12.1 + NODE_VERSION: 22.19.0 on: push: diff --git a/.github/workflows/release-program.yaml b/.github/workflows/release-program.yaml index e33277426..841d5aa5c 100644 --- a/.github/workflows/release-program.yaml +++ b/.github/workflows/release-program.yaml @@ -2,7 +2,7 @@ name: Release Program to Mainnet env: SOLANA_CLI_VERSION: 2.1.6 - NODE_VERSION: 18.12.1 + NODE_VERSION: 22.19.0 on: push: diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index d2ba9f756..166e6bf3c 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -10,7 +10,7 @@ on: - develop env: SOLANA_CLI_VERSION: 2.1.6 - NODE_VERSION: 18.12.1 + NODE_VERSION: 22.19.0 jobs: test-rust-lint: diff --git a/Anchor.toml b/Anchor.toml index c8274c4cc..102a7901b 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -81,6 +81,9 @@ address = "BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY" # bubblegum [[test.validator.clone]] address = "noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV" # noop +[[test.validator.clone]] +address = "4DdmDswskDxXGpwHrXUfn2CNUm9rt21ac79GHNTN3J33" # hnt feed needed for dc auto top + [[test.validator.clone]] address = "cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK" # account compression @@ -114,12 +117,19 @@ address = "stcfiqW3fwD9QCd8Bqr1NBLrs7dftZHBQe7RiMMA4aM" # State controller progr [[test.validator.clone]] address = "GPQNABq6s63uqzHRwZN9e2GcxtzG4yLP5AnJer7DkB9E" # State controller IDL +# Pyth price oracle program +[[test.validator.clone]] +address = "rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ" + +# Wormhole +[[test.validator.clone]] +address = "HDwcJBJXjL9FpJ7UBsYBtaDjsBUhuLCUYoz3zr8SWWaQ" + [[test.validator.clone]] -address = "DQ4C1tzvu28cwo1roN1Wm6TW35sfJEjLh517k3ZeWevx" # Mobile price oracle +address = "5gxPdahvSzcKySxXxPuRXZZ9s6h8hZ88XDVKavWpaQGn" -# Pyth price oracle [[test.validator.clone]] -address = "4DdmDswskDxXGpwHrXUfn2CNUm9rt21ac79GHNTN3J33" +address = "DaWUKXCyXsnzcvLUyeJRWou8KTn7XtadgTsdhJ6RHS7b" # Squads multisig program [[test.validator.clone]] diff --git a/migration-docker/Dockerfile b/migration-docker/Dockerfile index b07d3fb09..427663aaf 100644 --- a/migration-docker/Dockerfile +++ b/migration-docker/Dockerfile @@ -1,5 +1,5 @@ # Specify the base image -FROM node:20-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /app @@ -17,7 +17,7 @@ RUN lerna bootstrap RUN yarn run build -FROM node:20-alpine +FROM node:22-alpine WORKDIR /app diff --git a/packages/account-postgres-sink-service/Dockerfile b/packages/account-postgres-sink-service/Dockerfile index 33f55fafd..9e6920c99 100644 --- a/packages/account-postgres-sink-service/Dockerfile +++ b/packages/account-postgres-sink-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/active-device-oracle/Dockerfile b/packages/active-device-oracle/Dockerfile index 3c33d4747..9de672e3b 100644 --- a/packages/active-device-oracle/Dockerfile +++ b/packages/active-device-oracle/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/asset-ownership-service/Dockerfile b/packages/asset-ownership-service/Dockerfile index 91179e7cd..8cde05343 100644 --- a/packages/asset-ownership-service/Dockerfile +++ b/packages/asset-ownership-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/crons/Dockerfile b/packages/crons/Dockerfile index fe4be8fea..c5a5f74cb 100644 --- a/packages/crons/Dockerfile +++ b/packages/crons/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/crons/src/close-governance.ts b/packages/crons/src/close-governance.ts index 9c6972b56..bd8ec6803 100644 --- a/packages/crons/src/close-governance.ts +++ b/packages/crons/src/close-governance.ts @@ -13,6 +13,7 @@ import { populateMissingDraftInfo, sendAndConfirmWithRetry, toVersionedTx, + truthy, } from "@helium/spl-utils"; import { init as initState } from "@helium/state-controller-sdk"; import { init as initVsr, positionKey } from "@helium/voter-stake-registry-sdk"; @@ -158,9 +159,9 @@ async function getSolanaUnixTimestamp( a.account.index < b.account.index ? 1 : -1 ); - return await Promise.all( + return (await Promise.all( sortedProxies.map(async (proxy, index) => { - if (index === sortedProxies.length - 1) { + if (proxy.account.index === 0) { return proxyProgram.methods .closeExpiredProxyV0() .accountsPartial({ @@ -169,25 +170,27 @@ async function getSolanaUnixTimestamp( .instruction(); } - const prevProxyAssignment = new PublicKey( - sortedProxies[index + 1].publicKey - ); + if (proxy.account.index !== 0 && sortedProxies[index + 1]) { + const prevProxyAssignment = new PublicKey( + sortedProxies[index + 1].publicKey + ); - return proxyProgram.methods - .unassignExpiredProxyV0() - .accountsPartial({ - prevProxyAssignment, - proxyAssignment: new PublicKey(proxy.publicKey), - }) - .instruction(); + return proxyProgram.methods + .unassignExpiredProxyV0() + .accountsPartial({ + prevProxyAssignment, + proxyAssignment: new PublicKey(proxy.publicKey), + }) + .instruction(); + } }) - ); + )).filter(truthy); }) ); const txs = await batchInstructionsToTxsWithPriorityFee( provider, - multiDimArray.flat() + multiDimArray ); for (const tx of txs) { diff --git a/packages/currency-utils/package.json b/packages/currency-utils/package.json index e67f06223..f54b8e58d 100644 --- a/packages/currency-utils/package.json +++ b/packages/currency-utils/package.json @@ -28,6 +28,8 @@ "prebuild": "npm run clean && npm run package" }, "dependencies": { + "@helium/spl-utils": "^0.10.35", + "@pythnetwork/hermes-client": "^2.0.0", "@solana/spl-token": "^0.3.8", "@solana/web3.js": "^1.91.1" }, diff --git a/packages/currency-utils/src/currencyUtils.ts b/packages/currency-utils/src/currencyUtils.ts index 64268c27d..3721f4c5f 100644 --- a/packages/currency-utils/src/currencyUtils.ts +++ b/packages/currency-utils/src/currencyUtils.ts @@ -1,13 +1,8 @@ -import { Connection, PublicKey, Cluster } from "@solana/web3.js"; -import { getAssociatedTokenAddressSync, getAccount } from "@solana/spl-token"; -import { - PythSolanaReceiver, - IDL as pythSolanaReceiverIdl, -} from "./pyth"; -import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; - -export type { PythSolanaReceiver } from "./pyth"; -export { pythSolanaReceiverIdl }; +import { getAccount, getAssociatedTokenAddressSync } from "@solana/spl-token"; +import { Cluster, Connection, PublicKey } from "@solana/web3.js"; +import { HermesClient } from "@pythnetwork/hermes-client"; +import { HNT_PRICE_FEED_ID } from "@helium/spl-utils"; +import BN from "bn.js"; export const getBalance = async ({ pubKey, @@ -28,25 +23,55 @@ export const getBalance = async ({ } }; -export const getOraclePrice = async ({ - tokenType, - cluster, - connection, -}: { - tokenType: "HNT"; - cluster: Cluster; - connection: Connection; +export const PYTH_HERMES_URL = "https://hermes.pyth.network/" + +type PythReturn = { + priceMessage: { + emaPrice: { + feedId: number[] + price: BN + conf: BN + exponent: number + publishTime: BN + prevPublishTime: BN + emaPrice: BN + emaConf: BN + } + } +} + +export const getOraclePrice = async ({tokenType}: { + tokenType?: "HNT"; + cluster?: Cluster; + connection?: Connection; }) => { - const pythProgram: Program = new Program( - pythSolanaReceiverIdl as any, - new AnchorProvider(connection, {} as Wallet, { - skipPreflight: true, - }) + if (tokenType !== "HNT") { + throw new Error("Only HNT is supported"); + } + const priceServiceConnection = new HermesClient( + PYTH_HERMES_URL, + {} ); - const data = await pythProgram.account.priceUpdateV2.fetch( - new PublicKey("4DdmDswskDxXGpwHrXUfn2CNUm9rt21ac79GHNTN3J33") + const priceUpdates = ( + await priceServiceConnection.getLatestPriceUpdates( + [HNT_PRICE_FEED_ID], + { encoding: "base64" } + ) ); - - return data; + const price = priceUpdates.parsed![0]; + return { + priceMessage: { + emaPrice: { + feedId: HNT_PRICE_FEED_ID, + price: price.ema_price.price, + conf: price.ema_price.conf, + exponent: price.ema_price.expo, + publishTime: price.ema_price.publish_time, + prevPublishTime: price.ema_price.prev_publish_time, + emaPrice: price.ema_price.ema_price, + emaConf: price.ema_price.ema_conf, + } + } + } }; diff --git a/packages/currency-utils/src/pyth.ts b/packages/currency-utils/src/pyth.ts deleted file mode 100644 index d7679e0ea..000000000 --- a/packages/currency-utils/src/pyth.ts +++ /dev/null @@ -1,1257 +0,0 @@ -import { convertIdlToCamelCase } from "@coral-xyz/anchor/dist/cjs/idl"; - -/** - * Program IDL in camelCase format in order to be used in JS/TS. - * - * Note that this is only a type helper and is not the actual IDL. The original - * IDL can be found at `target/idl/pyth_solana_receiver.json`. - */ -export type PythSolanaReceiver = { - address: "rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ"; - metadata: { - name: "pythSolanaReceiver"; - version: "0.1.0"; - spec: "0.1.0"; - }; - instructions: [ - { - name: "initialize"; - discriminator: [175, 175, 109, 31, 13, 152, 155, 237]; - accounts: [ - { - name: "payer"; - writable: true; - signer: true; - }, - { - name: "config"; - writable: true; - }, - { - name: "systemProgram"; - } - ]; - args: [ - { - name: "initialConfig"; - type: { - defined: { - name: "config"; - }; - }; - } - ]; - }, - { - name: "requestGovernanceAuthorityTransfer"; - discriminator: [92, 18, 67, 156, 27, 151, 183, 224]; - accounts: [ - { - name: "payer"; - signer: true; - }, - { - name: "config"; - writable: true; - } - ]; - args: [ - { - name: "targetGovernanceAuthority"; - type: "pubkey"; - } - ]; - }, - { - name: "acceptGovernanceAuthorityTransfer"; - discriminator: [254, 39, 222, 79, 64, 217, 205, 127]; - accounts: [ - { - name: "payer"; - signer: true; - }, - { - name: "config"; - writable: true; - } - ]; - args: []; - }, - { - name: "setDataSources"; - discriminator: [107, 73, 15, 119, 195, 116, 91, 210]; - accounts: [ - { - name: "payer"; - signer: true; - }, - { - name: "config"; - writable: true; - } - ]; - args: [ - { - name: "validDataSources"; - type: { - vec: { - defined: { - name: "dataSource"; - }; - }; - }; - } - ]; - }, - { - name: "setFee"; - discriminator: [18, 154, 24, 18, 237, 214, 19, 80]; - accounts: [ - { - name: "payer"; - signer: true; - }, - { - name: "config"; - writable: true; - } - ]; - args: [ - { - name: "singleUpdateFeeInLamports"; - type: "u64"; - } - ]; - }, - { - name: "setWormholeAddress"; - discriminator: [154, 174, 252, 157, 91, 215, 179, 156]; - accounts: [ - { - name: "payer"; - signer: true; - }, - { - name: "config"; - writable: true; - } - ]; - args: [ - { - name: "wormhole"; - type: "pubkey"; - } - ]; - }, - { - name: "setMinimumSignatures"; - discriminator: [5, 210, 206, 124, 43, 68, 104, 149]; - accounts: [ - { - name: "payer"; - signer: true; - }, - { - name: "config"; - writable: true; - } - ]; - args: [ - { - name: "minimumSignatures"; - type: "u8"; - } - ]; - }, - { - name: "postUpdateAtomic"; - docs: [ - "Post a price update using a VAA and a MerklePriceUpdate.", - "This function allows you to post a price update in a single transaction.", - "Compared to post_update, it is less secure since you won't be able to verify all guardian signatures if you use this function because of transaction size limitations.", - "Typically, you can fit 5 guardian signatures in a transaction that uses this." - ]; - discriminator: [49, 172, 84, 192, 175, 180, 52, 234]; - accounts: [ - { - name: "payer"; - writable: true; - signer: true; - }, - { - name: "guardianSet"; - docs: [ - "Instead we do the same steps in deserialize_guardian_set_checked." - ]; - }, - { - name: "config"; - }, - { - name: "treasury"; - writable: true; - }, - { - name: "priceUpdateAccount"; - docs: [ - "The contraint is such that either the price_update_account is uninitialized or the payer is the write_authority.", - "Pubkey::default() is the SystemProgram on Solana and it can't sign so it's impossible that price_update_account.write_authority == Pubkey::default() once the account is initialized" - ]; - writable: true; - signer: true; - }, - { - name: "systemProgram"; - }, - { - name: "writeAuthority"; - signer: true; - } - ]; - args: [ - { - name: "params"; - type: { - defined: { - name: "postUpdateAtomicParams"; - }; - }; - } - ]; - }, - { - name: "postUpdate"; - docs: [ - "Post a price update using an encoded_vaa account and a MerklePriceUpdate calldata.", - "This should be called after the client has already verified the Vaa via the Wormhole contract.", - "Check out target_chains/solana/cli/src/main.rs for an example of how to do this." - ]; - discriminator: [133, 95, 207, 175, 11, 79, 118, 44]; - accounts: [ - { - name: "payer"; - writable: true; - signer: true; - }, - { - name: "encodedVaa"; - }, - { - name: "config"; - }, - { - name: "treasury"; - writable: true; - }, - { - name: "priceUpdateAccount"; - docs: [ - "The contraint is such that either the price_update_account is uninitialized or the payer is the write_authority.", - "Pubkey::default() is the SystemProgram on Solana and it can't sign so it's impossible that price_update_account.write_authority == Pubkey::default() once the account is initialized" - ]; - writable: true; - signer: true; - }, - { - name: "systemProgram"; - }, - { - name: "writeAuthority"; - signer: true; - } - ]; - args: [ - { - name: "params"; - type: { - defined: { - name: "postUpdateParams"; - }; - }; - } - ]; - }, - { - name: "reclaimRent"; - discriminator: [218, 200, 19, 197, 227, 89, 192, 22]; - accounts: [ - { - name: "payer"; - writable: true; - signer: true; - }, - { - name: "priceUpdateAccount"; - writable: true; - } - ]; - args: []; - } - ]; - accounts: [ - { - name: "config"; - discriminator: [155, 12, 170, 224, 30, 250, 204, 130]; - }, - { - name: "priceUpdateV2"; - discriminator: [34, 241, 35, 99, 157, 126, 244, 205]; - } - ]; - errors: [ - { - code: 6000; - name: "invalidWormholeMessage"; - msg: "Received an invalid wormhole message"; - }, - { - code: 6001; - name: "deserializeMessageFailed"; - msg: "An error occurred when deserializing the message"; - }, - { - code: 6002; - name: "invalidPriceUpdate"; - msg: "Received an invalid price update"; - }, - { - code: 6003; - name: "unsupportedMessageType"; - msg: "This type of message is not supported currently"; - }, - { - code: 6004; - name: "invalidDataSource"; - msg: "The tuple emitter chain, emitter doesn't match one of the valid data sources."; - }, - { - code: 6005; - name: "insufficientFunds"; - msg: "Funds are insufficient to pay the receiving fee"; - }, - { - code: 6006; - name: "wrongWriteAuthority"; - msg: "This signer can't write to price update account"; - }, - { - code: 6007; - name: "wrongVaaOwner"; - msg: "The posted VAA account has the wrong owner."; - }, - { - code: 6008; - name: "deserializeVaaFailed"; - msg: "An error occurred when deserializing the VAA."; - }, - { - code: 6009; - name: "insufficientGuardianSignatures"; - msg: "The number of guardian signatures is below the minimum"; - }, - { - code: 6010; - name: "invalidVaaVersion"; - msg: "Invalid VAA version"; - }, - { - code: 6011; - name: "guardianSetMismatch"; - msg: "Guardian set version in the VAA doesn't match the guardian set passed"; - }, - { - code: 6012; - name: "invalidGuardianOrder"; - msg: "Guardian signature indices must be increasing"; - }, - { - code: 6013; - name: "invalidGuardianIndex"; - msg: "Guardian index exceeds the number of guardians in the set"; - }, - { - code: 6014; - name: "invalidSignature"; - msg: "A VAA signature is invalid"; - }, - { - code: 6015; - name: "invalidGuardianKeyRecovery"; - msg: "The recovered guardian public key doesn't match the guardian set"; - }, - { - code: 6016; - name: "wrongGuardianSetOwner"; - msg: "The guardian set account is owned by the wrong program"; - }, - { - code: 6017; - name: "invalidGuardianSetPda"; - msg: "The Guardian Set account doesn't match the PDA derivation"; - }, - { - code: 6018; - name: "guardianSetExpired"; - msg: "The Guardian Set is expired"; - }, - { - code: 6019; - name: "governanceAuthorityMismatch"; - msg: "The signer is not authorized to perform this governance action"; - }, - { - code: 6020; - name: "targetGovernanceAuthorityMismatch"; - msg: "The signer is not authorized to accept the governance authority"; - }, - { - code: 6021; - name: "nonexistentGovernanceAuthorityTransferRequest"; - msg: "The governance authority needs to request a transfer first"; - } - ]; - types: [ - { - name: "priceFeedMessage"; - type: { - kind: "struct"; - fields: [ - { - name: "feedId"; - type: { - array: ["u8", 32]; - }; - }, - { - name: "price"; - type: "i64"; - }, - { - name: "conf"; - type: "u64"; - }, - { - name: "exponent"; - type: "i32"; - }, - { - name: "publishTime"; - type: "i64"; - }, - { - name: "prevPublishTime"; - type: "i64"; - }, - { - name: "emaPrice"; - type: "i64"; - }, - { - name: "emaConf"; - type: "u64"; - } - ]; - }; - }, - { - name: "merklePriceUpdate"; - type: { - kind: "struct"; - fields: [ - { - name: "message"; - type: "bytes"; - }, - { - name: "proof"; - type: { - vec: { - array: ["u8", 20]; - }; - }; - } - ]; - }; - }, - { - name: "dataSource"; - type: { - kind: "struct"; - fields: [ - { - name: "chain"; - type: "u16"; - }, - { - name: "emitter"; - type: "pubkey"; - } - ]; - }; - }, - { - name: "postUpdateAtomicParams"; - type: { - kind: "struct"; - fields: [ - { - name: "vaa"; - type: "bytes"; - }, - { - name: "merklePriceUpdate"; - type: { - defined: { - name: "merklePriceUpdate"; - }; - }; - }, - { - name: "treasuryId"; - type: "u8"; - } - ]; - }; - }, - { - name: "postUpdateParams"; - type: { - kind: "struct"; - fields: [ - { - name: "merklePriceUpdate"; - type: { - defined: { - name: "merklePriceUpdate"; - }; - }; - }, - { - name: "treasuryId"; - type: "u8"; - } - ]; - }; - }, - { - name: "verificationLevel"; - docs: [ - "* This enum represents how many guardian signatures were checked for a Pythnet price update\n * If full, guardian quorum has been attained\n * If partial, at least config.minimum signatures have been verified, but in the case config.minimum_signatures changes in the future we also include the number of signatures that were checked" - ]; - type: { - kind: "enum"; - variants: [ - { - name: "partial"; - fields: [ - { - name: "numSignatures"; - type: "u8"; - } - ]; - }, - { - name: "full"; - } - ]; - }; - }, - { - name: "config"; - type: { - kind: "struct"; - fields: [ - { - name: "governanceAuthority"; - type: "pubkey"; - }, - { - name: "targetGovernanceAuthority"; - type: { - option: "pubkey"; - }; - }, - { - name: "wormhole"; - type: "pubkey"; - }, - { - name: "validDataSources"; - type: { - vec: { - defined: { - name: "dataSource"; - }; - }; - }; - }, - { - name: "singleUpdateFeeInLamports"; - type: "u64"; - }, - { - name: "minimumSignatures"; - type: "u8"; - } - ]; - }; - }, - { - name: "priceUpdateV2"; - type: { - kind: "struct"; - fields: [ - { - name: "writeAuthority"; - type: "pubkey"; - }, - { - name: "verificationLevel"; - type: { - defined: { - name: "verificationLevel"; - }; - }; - }, - { - name: "priceMessage"; - type: { - defined: { - name: "priceFeedMessage"; - }; - }; - }, - { - name: "postedSlot"; - type: "u64"; - } - ]; - }; - } - ]; -}; - -export const IDL = convertIdlToCamelCase({ - address: "rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ", - metadata: { - name: "pyth_solana_receiver", - version: "0.1.0", - spec: "0.1.0", - }, - instructions: [ - { - name: "initialize", - discriminator: [175, 175, 109, 31, 13, 152, 155, 237], - accounts: [ - { - name: "payer", - writable: true, - signer: true, - }, - { - name: "config", - writable: true, - }, - { - name: "system_program", - }, - ], - args: [ - { - name: "initial_config", - type: { - defined: { - name: "Config", - }, - }, - }, - ], - }, - { - name: "request_governance_authority_transfer", - discriminator: [92, 18, 67, 156, 27, 151, 183, 224], - accounts: [ - { - name: "payer", - signer: true, - }, - { - name: "config", - writable: true, - }, - ], - args: [ - { - name: "target_governance_authority", - type: "pubkey", - }, - ], - }, - { - name: "accept_governance_authority_transfer", - discriminator: [254, 39, 222, 79, 64, 217, 205, 127], - accounts: [ - { - name: "payer", - signer: true, - }, - { - name: "config", - writable: true, - }, - ], - args: [], - }, - { - name: "set_data_sources", - discriminator: [107, 73, 15, 119, 195, 116, 91, 210], - accounts: [ - { - name: "payer", - signer: true, - }, - { - name: "config", - writable: true, - }, - ], - args: [ - { - name: "valid_data_sources", - type: { - vec: { - defined: { - name: "DataSource", - }, - }, - }, - }, - ], - }, - { - name: "set_fee", - discriminator: [18, 154, 24, 18, 237, 214, 19, 80], - accounts: [ - { - name: "payer", - signer: true, - }, - { - name: "config", - writable: true, - }, - ], - args: [ - { - name: "single_update_fee_in_lamports", - type: "u64", - }, - ], - }, - { - name: "set_wormhole_address", - discriminator: [154, 174, 252, 157, 91, 215, 179, 156], - accounts: [ - { - name: "payer", - signer: true, - }, - { - name: "config", - writable: true, - }, - ], - args: [ - { - name: "wormhole", - type: "pubkey", - }, - ], - }, - { - name: "set_minimum_signatures", - discriminator: [5, 210, 206, 124, 43, 68, 104, 149], - accounts: [ - { - name: "payer", - signer: true, - }, - { - name: "config", - writable: true, - }, - ], - args: [ - { - name: "minimum_signatures", - type: "u8", - }, - ], - }, - { - name: "post_update_atomic", - docs: [ - "Post a price update using a VAA and a MerklePriceUpdate.", - "This function allows you to post a price update in a single transaction.", - "Compared to post_update, it is less secure since you won't be able to verify all guardian signatures if you use this function because of transaction size limitations.", - "Typically, you can fit 5 guardian signatures in a transaction that uses this.", - ], - discriminator: [49, 172, 84, 192, 175, 180, 52, 234], - accounts: [ - { - name: "payer", - writable: true, - signer: true, - }, - { - name: "guardian_set", - docs: [ - "Instead we do the same steps in deserialize_guardian_set_checked.", - ], - }, - { - name: "config", - }, - { - name: "treasury", - writable: true, - }, - { - name: "price_update_account", - docs: [ - "The contraint is such that either the price_update_account is uninitialized or the payer is the write_authority.", - "Pubkey::default() is the SystemProgram on Solana and it can't sign so it's impossible that price_update_account.write_authority == Pubkey::default() once the account is initialized", - ], - writable: true, - signer: true, - }, - { - name: "system_program", - }, - { - name: "write_authority", - signer: true, - }, - ], - args: [ - { - name: "params", - type: { - defined: { - name: "PostUpdateAtomicParams", - }, - }, - }, - ], - }, - { - name: "post_update", - docs: [ - "Post a price update using an encoded_vaa account and a MerklePriceUpdate calldata.", - "This should be called after the client has already verified the Vaa via the Wormhole contract.", - "Check out target_chains/solana/cli/src/main.rs for an example of how to do this.", - ], - discriminator: [133, 95, 207, 175, 11, 79, 118, 44], - accounts: [ - { - name: "payer", - writable: true, - signer: true, - }, - { - name: "encoded_vaa", - }, - { - name: "config", - }, - { - name: "treasury", - writable: true, - }, - { - name: "price_update_account", - docs: [ - "The contraint is such that either the price_update_account is uninitialized or the payer is the write_authority.", - "Pubkey::default() is the SystemProgram on Solana and it can't sign so it's impossible that price_update_account.write_authority == Pubkey::default() once the account is initialized", - ], - writable: true, - signer: true, - }, - { - name: "system_program", - }, - { - name: "write_authority", - signer: true, - }, - ], - args: [ - { - name: "params", - type: { - defined: { - name: "PostUpdateParams", - }, - }, - }, - ], - }, - { - name: "reclaim_rent", - discriminator: [218, 200, 19, 197, 227, 89, 192, 22], - accounts: [ - { - name: "payer", - writable: true, - signer: true, - }, - { - name: "price_update_account", - writable: true, - }, - ], - args: [], - }, - ], - accounts: [ - { - name: "Config", - discriminator: [155, 12, 170, 224, 30, 250, 204, 130], - }, - { - name: "priceUpdateV2", - discriminator: [34, 241, 35, 99, 157, 126, 244, 205], - }, - ], - errors: [ - { - code: 6000, - name: "InvalidWormholeMessage", - msg: "Received an invalid wormhole message", - }, - { - code: 6001, - name: "DeserializeMessageFailed", - msg: "An error occurred when deserializing the message", - }, - { - code: 6002, - name: "InvalidPriceUpdate", - msg: "Received an invalid price update", - }, - { - code: 6003, - name: "UnsupportedMessageType", - msg: "This type of message is not supported currently", - }, - { - code: 6004, - name: "InvalidDataSource", - msg: "The tuple emitter chain, emitter doesn't match one of the valid data sources.", - }, - { - code: 6005, - name: "InsufficientFunds", - msg: "Funds are insufficient to pay the receiving fee", - }, - { - code: 6006, - name: "WrongWriteAuthority", - msg: "This signer can't write to price update account", - }, - { - code: 6007, - name: "WrongVaaOwner", - msg: "The posted VAA account has the wrong owner.", - }, - { - code: 6008, - name: "DeserializeVaaFailed", - msg: "An error occurred when deserializing the VAA.", - }, - { - code: 6009, - name: "InsufficientGuardianSignatures", - msg: "The number of guardian signatures is below the minimum", - }, - { - code: 6010, - name: "InvalidVaaVersion", - msg: "Invalid VAA version", - }, - { - code: 6011, - name: "GuardianSetMismatch", - msg: "Guardian set version in the VAA doesn't match the guardian set passed", - }, - { - code: 6012, - name: "InvalidGuardianOrder", - msg: "Guardian signature indices must be increasing", - }, - { - code: 6013, - name: "InvalidGuardianIndex", - msg: "Guardian index exceeds the number of guardians in the set", - }, - { - code: 6014, - name: "InvalidSignature", - msg: "A VAA signature is invalid", - }, - { - code: 6015, - name: "InvalidGuardianKeyRecovery", - msg: "The recovered guardian public key doesn't match the guardian set", - }, - { - code: 6016, - name: "WrongGuardianSetOwner", - msg: "The guardian set account is owned by the wrong program", - }, - { - code: 6017, - name: "InvalidGuardianSetPda", - msg: "The Guardian Set account doesn't match the PDA derivation", - }, - { - code: 6018, - name: "GuardianSetExpired", - msg: "The Guardian Set is expired", - }, - { - code: 6019, - name: "GovernanceAuthorityMismatch", - msg: "The signer is not authorized to perform this governance action", - }, - { - code: 6020, - name: "TargetGovernanceAuthorityMismatch", - msg: "The signer is not authorized to accept the governance authority", - }, - { - code: 6021, - name: "NonexistentGovernanceAuthorityTransferRequest", - msg: "The governance authority needs to request a transfer first", - }, - ], - types: [ - { - name: "PriceFeedMessage", - type: { - kind: "struct", - fields: [ - { - name: "feed_id", - type: { - array: ["u8", 32], - }, - }, - { - name: "price", - type: "i64", - }, - { - name: "conf", - type: "u64", - }, - { - name: "exponent", - type: "i32", - }, - { - name: "publish_time", - type: "i64", - }, - { - name: "prev_publish_time", - type: "i64", - }, - { - name: "ema_price", - type: "i64", - }, - { - name: "ema_conf", - type: "u64", - }, - ], - }, - }, - { - name: "MerklePriceUpdate", - type: { - kind: "struct", - fields: [ - { - name: "message", - type: "bytes", - }, - { - name: "proof", - type: { - vec: { - array: ["u8", 20], - }, - }, - }, - ], - }, - }, - { - name: "DataSource", - type: { - kind: "struct", - fields: [ - { - name: "chain", - type: "u16", - }, - { - name: "emitter", - type: "pubkey", - }, - ], - }, - }, - { - name: "PostUpdateAtomicParams", - type: { - kind: "struct", - fields: [ - { - name: "vaa", - type: "bytes", - }, - { - name: "merkle_price_update", - type: { - defined: { - name: "MerklePriceUpdate", - }, - }, - }, - { - name: "treasury_id", - type: "u8", - }, - ], - }, - }, - { - name: "PostUpdateParams", - type: { - kind: "struct", - fields: [ - { - name: "merkle_price_update", - type: { - defined: { - name: "MerklePriceUpdate", - }, - }, - }, - { - name: "treasury_id", - type: "u8", - }, - ], - }, - }, - { - name: "VerificationLevel", - docs: [ - "* This enum represents how many guardian signatures were checked for a Pythnet price update\n * If full, guardian quorum has been attained\n * If partial, at least config.minimum signatures have been verified, but in the case config.minimum_signatures changes in the future we also include the number of signatures that were checked", - ], - type: { - kind: "enum", - variants: [ - { - name: "Partial", - fields: [ - { - name: "num_signatures", - type: "u8", - }, - ], - }, - { - name: "Full", - }, - ], - }, - }, - { - name: "Config", - type: { - kind: "struct", - fields: [ - { - name: "governance_authority", - type: "pubkey", - }, - { - name: "target_governance_authority", - type: { - option: "pubkey", - }, - }, - { - name: "wormhole", - type: "pubkey", - }, - { - name: "valid_data_sources", - type: { - vec: { - defined: { - name: "DataSource", - }, - }, - }, - }, - { - name: "single_update_fee_in_lamports", - type: "u64", - }, - { - name: "minimum_signatures", - type: "u8", - }, - ], - }, - }, - { - name: "priceUpdateV2", - type: { - kind: "struct", - fields: [ - { - name: "write_authority", - type: "pubkey", - }, - { - name: "verification_level", - type: { - defined: { - name: "VerificationLevel", - }, - }, - }, - { - name: "price_message", - type: { - defined: { - name: "PriceFeedMessage", - }, - }, - }, - { - name: "posted_slot", - type: "u64", - }, - ], - }, - }, - ], -}); diff --git a/packages/currency-utils/tsconfig.json b/packages/currency-utils/tsconfig.json index 3c7c4e611..edbc2cd18 100644 --- a/packages/currency-utils/tsconfig.json +++ b/packages/currency-utils/tsconfig.json @@ -1,6 +1,9 @@ { "extends": "../../tsconfig.root.json", "references": [ + { + "path": "../spl-utils" + }, { "path": "./tsconfig.cjs.json" }, diff --git a/packages/currency-utils/yarn.deploy.lock b/packages/currency-utils/yarn.deploy.lock index 5c5e5fe31..378f435d6 100644 --- a/packages/currency-utils/yarn.deploy.lock +++ b/packages/currency-utils/yarn.deploy.lock @@ -23,15 +23,115 @@ __metadata: languageName: node linkType: hard +"@coral-xyz/anchor-errors@npm:^0.31.0": + version: 0.31.0 + resolution: "@coral-xyz/anchor-errors@npm:0.31.0" + checksum: beb42facd19f2c8f32478eed76e2fa20c3cee8be6a2790b4c8cb8eeaca88b5f1da1a2b14d38ac662f23788fcb3bd9573a90285397425621b740a4b422e4e214b + languageName: node + linkType: hard + +"@coral-xyz/anchor@npm:^0.31.0": + version: 0.31.0 + resolution: "@coral-xyz/anchor@npm:0.31.0" + dependencies: + "@coral-xyz/anchor-errors": ^0.31.0 + "@coral-xyz/borsh": ^0.31.0 + "@noble/hashes": ^1.3.1 + "@solana/web3.js": ^1.69.0 + bn.js: ^5.1.2 + bs58: ^4.0.1 + buffer-layout: ^1.2.2 + camelcase: ^6.3.0 + cross-fetch: ^3.1.5 + eventemitter3: ^4.0.7 + pako: ^2.0.3 + superstruct: ^0.15.4 + toml: ^3.0.0 + checksum: b74942b4066567640ad224de3a1d7d49f6d1e246f10508ed6e765981d3b0766a73ab0fd2ec6f21f3c3baacdf776eb569fc73bd9a3690790c20bdc8f6d237bad4 + languageName: node + linkType: hard + +"@coral-xyz/borsh@npm:^0.31.0": + version: 0.31.0 + resolution: "@coral-xyz/borsh@npm:0.31.0" + dependencies: + bn.js: ^5.1.2 + buffer-layout: ^1.2.0 + peerDependencies: + "@solana/web3.js": ^1.69.0 + checksum: 73d6d838662182c39f2230366d9bfbb5bb8120cc31fa6141ddf6dd445a6c719a920dd40d475c64ecaa953eda7e0516a05fc134c08e344350d4a284374a4edb94 + languageName: node + linkType: hard + +"@helium/account-fetch-cache@^0.10.35": + version: 0.0.0-use.local + resolution: "@helium/account-fetch-cache@workspace:packages/account-fetch-cache" + dependencies: + "@solana/web3.js": ^1.91.1 + git-format-staged: ^2.1.3 + ts-loader: ^9.2.3 + typescript: ^5.2.2 + languageName: unknown + linkType: soft + +"@helium/address@npm:^4.12.0": + version: 4.12.0 + resolution: "@helium/address@npm:4.12.0" + dependencies: + bs58: ^5.0.0 + js-sha256: ^0.9.0 + multiformats: ^9.6.4 + checksum: d4ea0fd0ea565776cd2bf70835235784d87e483436328648b2b7605f6c2c93a6baa35a6b56f7e8b571d3a7417888da66638e262db1204b2abb3b0500d37ba7e0 + languageName: node + linkType: hard + +"@helium/anchor-resolvers@^0.10.35": + version: 0.0.0-use.local + resolution: "@helium/anchor-resolvers@workspace:packages/anchor-resolvers" + dependencies: + "@solana/spl-token": ^0.3.8 + "@solana/web3.js": ^1.91.1 + git-format-staged: ^2.1.3 + ts-loader: ^9.2.3 + typescript: ^5.2.2 + peerDependencies: + "@coral-xyz/anchor": ^0.31.0 + languageName: unknown + linkType: soft + "@helium/currency-utils@workspace:.": version: 0.0.0-use.local resolution: "@helium/currency-utils@workspace:." dependencies: + "@helium/spl-utils": ^0.10.35 + "@pythnetwork/hermes-client": ^2.0.0 "@solana/spl-token": ^0.3.8 "@solana/web3.js": ^1.91.1 languageName: unknown linkType: soft +"@helium/spl-utils@^0.10.35": + version: 0.0.0-use.local + resolution: "@helium/spl-utils@workspace:packages/spl-utils" + dependencies: + "@coral-xyz/anchor": ^0.31.0 + "@helium/account-fetch-cache": ^0.10.35 + "@helium/address": ^4.12.0 + "@helium/anchor-resolvers": ^0.10.35 + "@metaplex-foundation/mpl-token-metadata": ^2.10.0 + "@solana/spl-account-compression": ^0.1.7 + "@solana/spl-token": ^0.3.8 + "@solana/web3.js": ^1.91.1 + axios: ^1.9.0 + bn.js: ^5.2.0 + borsh: ^0.7.0 + bs58: ^4.0.1 + git-format-staged: ^2.1.3 + ts-loader: ^9.2.3 + typescript: ^5.2.2 + languageName: unknown + linkType: soft + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -46,6 +146,51 @@ __metadata: languageName: node linkType: hard +"@metaplex-foundation/beet-solana@npm:^0.4.0": + version: 0.4.0 + resolution: "@metaplex-foundation/beet-solana@npm:0.4.0" + dependencies: + "@metaplex-foundation/beet": "npm:>=0.1.0" + "@solana/web3.js": "npm:^1.56.2" + bs58: "npm:^5.0.0" + debug: "npm:^4.3.4" + checksum: ee746c2d15f985c31d133d4ee29efbda445877473cc32aafa4b684ce3fa9a916ddff30d0e3cfef7654ff5725adff59a62a635c76bc781a6e1362c5b5d3137ed0 + languageName: node + linkType: hard + +"@metaplex-foundation/beet@npm:>=0.1.0, @metaplex-foundation/beet@npm:^0.7.1": + version: 0.7.1 + resolution: "@metaplex-foundation/beet@npm:0.7.1" + dependencies: + ansicolors: "npm:^0.3.2" + bn.js: "npm:^5.2.0" + debug: "npm:^4.3.3" + checksum: f8a330073ab1a0976478e9847c0e63e32f7bee67ea6306e1f89784e8275e30daaecba7cbc5f3424e5d96c411aa3bfbc2b638c105a90067a985acdfbd33a1a287 + languageName: node + linkType: hard + +"@metaplex-foundation/cusper@npm:^0.0.2": + version: 0.0.2 + resolution: "@metaplex-foundation/cusper@npm:0.0.2" + checksum: d157953baf42a2a012cdeb809c1785f29a44d80a3b5a3841c930baeb12ac6ddcf37f1a15eded4dce20d66f7bc8f23bedb87e905758df721e274bfcd816e70ba1 + languageName: node + linkType: hard + +"@metaplex-foundation/mpl-token-metadata@npm:^2.10.0": + version: 2.13.0 + resolution: "@metaplex-foundation/mpl-token-metadata@npm:2.13.0" + dependencies: + "@metaplex-foundation/beet": "npm:^0.7.1" + "@metaplex-foundation/beet-solana": "npm:^0.4.0" + "@metaplex-foundation/cusper": "npm:^0.0.2" + "@solana/spl-token": "npm:^0.3.6" + "@solana/web3.js": "npm:^1.66.2" + bn.js: "npm:^5.2.0" + debug: "npm:^4.3.4" + checksum: 89f82980f435ac45d961e6ab03859c7e4ab9809ad2d9f84aca91bcf50fdc60e210d0596d8856adf63e474ca69d971c51a4c27d0fe4dab115fcef64d57f3be611 + languageName: node + linkType: hard + "@noble/curves@npm:^1.0.0": version: 1.2.0 resolution: "@noble/curves@npm:1.2.0" @@ -101,6 +246,17 @@ __metadata: languageName: node linkType: hard +"@pythnetwork/hermes-client@npm:^2.0.0": + version: 2.0.0 + resolution: "@pythnetwork/hermes-client@npm:2.0.0" + dependencies: + "@zodios/core": ^10.9.6 + eventsource: ^3.0.5 + zod: ^3.23.8 + checksum: d5432c7c83617993a8e32fa4fde578e3b167ea348e5d3e2c681ee7bcf0e311824e00423d5529628f376f3541c888b9a12ed6c04135ea2e2f5872ab638a2dd31c + languageName: node + linkType: hard + "@solana/buffer-layout-utils@npm:^0.2.0": version: 0.2.0 resolution: "@solana/buffer-layout-utils@npm:0.2.0" @@ -122,7 +278,23 @@ __metadata: languageName: node linkType: hard -"@solana/spl-token@npm:^0.3.8": +"@solana/spl-account-compression@npm:^0.1.7": + version: 0.1.10 + resolution: "@solana/spl-account-compression@npm:0.1.10" + dependencies: + "@metaplex-foundation/beet": "npm:^0.7.1" + "@metaplex-foundation/beet-solana": "npm:^0.4.0" + bn.js: "npm:^5.2.1" + borsh: "npm:^0.7.0" + js-sha3: "npm:^0.8.0" + typescript-collections: "npm:^1.3.3" + peerDependencies: + "@solana/web3.js": ^1.50.1 + checksum: 99bd851933c46a068dbd13484770edd7ae12488b1474ee2e9d7dfd114087f3f9f813745795f91278142fbeb09aec1024f74ef2d2c8be2b47f1df319d37f0af11 + languageName: node + linkType: hard + +"@solana/spl-token@npm:^0.3.6, @solana/spl-token@npm:^0.3.8": version: 0.3.8 resolution: "@solana/spl-token@npm:0.3.8" dependencies: @@ -135,7 +307,7 @@ __metadata: languageName: node linkType: hard -"@solana/web3.js@npm:^1.32.0": +"@solana/web3.js@npm:^1.32.0, @solana/web3.js@npm:^1.56.2, @solana/web3.js@npm:^1.66.2": version: 1.78.4 resolution: "@solana/web3.js@npm:1.78.4" dependencies: @@ -158,7 +330,7 @@ __metadata: languageName: node linkType: hard -"@solana/web3.js@npm:^1.91.1": +"@solana/web3.js@npm:^1.69.0, @solana/web3.js@npm:^1.91.1": version: 1.98.0 resolution: "@solana/web3.js@npm:1.98.0" dependencies: @@ -245,6 +417,16 @@ __metadata: languageName: node linkType: hard +"@zodios/core@npm:^10.9.6": + version: 10.9.6 + resolution: "@zodios/core@npm:10.9.6" + peerDependencies: + axios: ^0.x || ^1.0.0 + zod: ^3.x + checksum: 482a80bd4da661734f9ed276a92d9275fa1b76011bef26ede4a851e4c495d9103e6c9456074b9e50e4c89ad7e83fcead6ea45ffba615e6ff54b8088433ba47fc + languageName: node + linkType: hard + "JSONStream@npm:^1.3.5": version: 1.3.5 resolution: "JSONStream@npm:1.3.5" @@ -306,7 +488,7 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^4.0.0": +"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": version: 4.3.0 resolution: "ansi-styles@npm:4.3.0" dependencies: @@ -322,6 +504,13 @@ __metadata: languageName: node linkType: hard +"ansicolors@npm:^0.3.2": + version: 0.3.2 + resolution: "ansicolors@npm:0.3.2" + checksum: e84fae7ebc27ac96d9dbb57f35f078cd6dde1b7046b0f03f73dcefc9fbb1f2e82e3685d083466aded8faf038f9fa9ebb408d215282bcd7aaa301d5ac3c486815 + languageName: node + linkType: hard + "aproba@npm:^1.0.3 || ^2.0.0": version: 2.0.0 resolution: "aproba@npm:2.0.0" @@ -339,6 +528,24 @@ __metadata: languageName: node linkType: hard +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: 7b78c451df768adba04e2d02e63e2d0bf3b07adcd6e42b4cf665cb7ce899bedd344c69a1dcbce355b5f972d597b25aaa1c1742b52cffd9caccb22f348114f6be + languageName: node + linkType: hard + +"axios@npm:^1.9.0": + version: 1.9.0 + resolution: "axios@npm:1.9.0" + dependencies: + follow-redirects: ^1.15.6 + form-data: ^4.0.0 + proxy-from-env: ^1.1.0 + checksum: 631f02c9c279f2ae90637a4989cc9d75c1c27aefd16b6e8eb90f98a4d0bddaccfd1cb1387be12101d1ab0f9bbf0c47e2451b4de0cf2870462a7d9ed3de8da3f2 + languageName: node + linkType: hard + "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -355,6 +562,13 @@ __metadata: languageName: node linkType: hard +"base-x@npm:^4.0.0": + version: 4.0.0 + resolution: "base-x@npm:4.0.0" + checksum: b25db9e07eb1998472a20557c7f00c797dc0595f79df95155ab74274e7fa98b9f2659b3ee547ac8773666b7f69540656793aeb97ad2b1ceccdb6fa5faaf69ac0 + languageName: node + linkType: hard + "base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -388,7 +602,7 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": +"bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": version: 5.2.1 resolution: "bn.js@npm:5.2.1" checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 @@ -425,6 +639,15 @@ __metadata: languageName: node linkType: hard +"braces@npm:^3.0.2": + version: 3.0.2 + resolution: "braces@npm:3.0.2" + dependencies: + fill-range: "npm:^7.0.1" + checksum: e2a8e769a863f3d4ee887b5fe21f63193a891c68b612ddb4b68d82d1b5f3ff9073af066c343e9867a393fe4c2555dcb33e89b937195feb9c1613d259edfcd459 + languageName: node + linkType: hard + "bs58@npm:^4.0.0, bs58@npm:^4.0.1": version: 4.0.1 resolution: "bs58@npm:4.0.1" @@ -434,6 +657,22 @@ __metadata: languageName: node linkType: hard +"bs58@npm:^5.0.0": + version: 5.0.0 + resolution: "bs58@npm:5.0.0" + dependencies: + base-x: "npm:^4.0.0" + checksum: 2475cb0684e07077521aac718e604a13e0f891d58cff923d437a2f7e9e28703ab39fce9f84c7c703ab369815a675f11e3bd394d38643bfe8969fbe42e6833d45 + languageName: node + linkType: hard + +"buffer-layout@npm:^1.2.0, buffer-layout@npm:^1.2.2": + version: 1.2.2 + resolution: "buffer-layout@npm:1.2.2" + checksum: e5809ba275530bf4e52fd09558b7c2111fbda5b405124f581acf364261d9c154e271800271898cd40473f9bcbb42c31584efb04219bde549d3460ca4bafeaa07 + languageName: node + linkType: hard + "buffer@npm:6.0.3, buffer@npm:^6.0.3, buffer@npm:~6.0.3": version: 6.0.3 resolution: "buffer@npm:6.0.3" @@ -474,6 +713,33 @@ __metadata: languageName: node linkType: hard +"call-bind-apply-helpers@npm:^1.0.1": + version: 1.0.1 + resolution: "call-bind-apply-helpers@npm:1.0.1" + dependencies: + es-errors: ^1.3.0 + function-bind: ^1.1.2 + checksum: 3c55343261bb387c58a4762d15ad9d42053659a62681ec5eb50690c6b52a4a666302a01d557133ce6533e8bd04530ee3b209f23dd06c9577a1925556f8fcccdf + languageName: node + linkType: hard + +"camelcase@npm:^6.3.0": + version: 6.3.0 + resolution: "camelcase@npm:6.3.0" + checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d + languageName: node + linkType: hard + +"chalk@npm:^4.1.0": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: "npm:^4.1.0" + supports-color: "npm:^7.1.0" + checksum: fe75c9d5c76a7a98d45495b91b2172fa3b7a09e0cc9370e5c8feb1c567b85c4288e2b3fded7cfdd7359ac28d6b3844feb8b82b8686842e93d23c827c417e83fc + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -513,6 +779,15 @@ __metadata: languageName: node linkType: hard +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: "npm:~1.0.0" + checksum: 49fa4aeb4916567e33ea81d088f6584749fc90c7abec76fd516bf1c5aa5c79f3584b5ba3de6b86d26ddd64bae5329c4c7479343250cfe71c75bb366eae53bb7c + languageName: node + linkType: hard + "commander@npm:^2.20.3": version: 2.20.3 resolution: "commander@npm:2.20.3" @@ -534,6 +809,15 @@ __metadata: languageName: node linkType: hard +"cross-fetch@npm:^3.1.5": + version: 3.1.8 + resolution: "cross-fetch@npm:3.1.8" + dependencies: + node-fetch: "npm:^2.6.12" + checksum: 78f993fa099eaaa041122ab037fe9503ecbbcb9daef234d1d2e0b9230a983f64d645d088c464e21a247b825a08dc444a6e7064adfa93536d3a9454b4745b3632 + languageName: node + linkType: hard + "cross-spawn@npm:^7.0.0": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" @@ -545,7 +829,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.3.3": +"debug@npm:4, debug@npm:^4.3.3, debug@npm:^4.3.4": version: 4.3.4 resolution: "debug@npm:4.3.4" dependencies: @@ -564,6 +848,13 @@ __metadata: languageName: node linkType: hard +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: 46fe6e83e2cb1d85ba50bd52803c68be9bd953282fa7096f51fc29edd5d67ff84ff753c51966061e5ba7cb5e47ef6d36a91924eddb7f3f3483b1c560f77a0020 + languageName: node + linkType: hard + "delegates@npm:^1.0.0": version: 1.0.0 resolution: "delegates@npm:1.0.0" @@ -571,6 +862,17 @@ __metadata: languageName: node linkType: hard +"dunder-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "dunder-proto@npm:1.0.1" + dependencies: + call-bind-apply-helpers: ^1.0.1 + es-errors: ^1.3.0 + gopd: ^1.2.0 + checksum: 149207e36f07bd4941921b0ca929e3a28f1da7bd6b6ff8ff7f4e2f2e460675af4576eeba359c635723dc189b64cdd4787e0255897d5b135ccc5d15cb8685fc90 + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -601,6 +903,16 @@ __metadata: languageName: node linkType: hard +"enhanced-resolve@npm:^5.0.0": + version: 5.15.0 + resolution: "enhanced-resolve@npm:5.15.0" + dependencies: + graceful-fs: "npm:^4.2.4" + tapable: "npm:^2.2.0" + checksum: fbd8cdc9263be71cc737aa8a7d6c57b43d6aa38f6cc75dde6fcd3598a130cc465f979d2f4d01bb3bf475acb43817749c79f8eef9be048683602ca91ab52e4f11 + languageName: node + linkType: hard + "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -615,6 +927,41 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.1": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 0512f4e5d564021c9e3a644437b0155af2679d10d80f21adaf868e64d30efdfbd321631956f20f42d655fedb2e3a027da479fad3fa6048f768eb453a80a5f80a + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 + languageName: node + linkType: hard + +"es-object-atoms@npm:^1.0.0": + version: 1.0.0 + resolution: "es-object-atoms@npm:1.0.0" + dependencies: + es-errors: ^1.3.0 + checksum: 26f0ff78ab93b63394e8403c353842b2272836968de4eafe97656adfb8a7c84b9099bf0fe96ed58f4a4cddc860f6e34c77f91649a58a5daa4a9c40b902744e3c + languageName: node + linkType: hard + +"es-set-tostringtag@npm:^2.1.0": + version: 2.1.0 + resolution: "es-set-tostringtag@npm:2.1.0" + dependencies: + es-errors: ^1.3.0 + get-intrinsic: ^1.2.6 + has-tostringtag: ^1.0.2 + hasown: ^2.0.2 + checksum: 789f35de4be3dc8d11fdcb91bc26af4ae3e6d602caa93299a8c45cf05d36cc5081454ae2a6d3afa09cceca214b76c046e4f8151e092e6fc7feeb5efb9e794fc6 + languageName: node + linkType: hard + "es6-promise@npm:^4.0.3": version: 4.2.8 resolution: "es6-promise@npm:4.2.8" @@ -645,6 +992,22 @@ __metadata: languageName: node linkType: hard +"eventsource-parser@npm:^3.0.1": + version: 3.0.3 + resolution: "eventsource-parser@npm:3.0.3" + checksum: a052aaedb89da8744219aea539343dabc54c6e032acc47f182a90fbbb083583208fbe0f786d7bc1182da098c88a391b7881b59a3fc921a73b718f25d1ee37425 + languageName: node + linkType: hard + +"eventsource@npm:^3.0.5": + version: 3.0.7 + resolution: "eventsource@npm:3.0.7" + dependencies: + eventsource-parser: ^3.0.1 + checksum: cd8cbc3418238b9d751b6652edf442d4b869829fbc3b73444abca1816fe3d23dc707130dd9a990360bc27c281d986f2f62059d870921173425c3ac28d20a8414 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -673,6 +1036,25 @@ __metadata: languageName: node linkType: hard +"fill-range@npm:^7.0.1": + version: 7.0.1 + resolution: "fill-range@npm:7.0.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: cc283f4e65b504259e64fd969bcf4def4eb08d85565e906b7d36516e87819db52029a76b6363d0f02d0d532f0033c9603b9e2d943d56ee3b0d4f7ad3328ff917 + languageName: node + linkType: hard + +"follow-redirects@npm:^1.15.6": + version: 1.15.9 + resolution: "follow-redirects@npm:1.15.9" + peerDependenciesMeta: + debug: + optional: true + checksum: 859e2bacc7a54506f2bf9aacb10d165df78c8c1b0ceb8023f966621b233717dab56e8d08baadc3ad3b9db58af290413d585c999694b7c146aaf2616340c3d2a6 + languageName: node + linkType: hard + "foreground-child@npm:^3.1.0": version: 3.1.1 resolution: "foreground-child@npm:3.1.1" @@ -683,6 +1065,19 @@ __metadata: languageName: node linkType: hard +"form-data@npm:^4.0.0": + version: 4.0.4 + resolution: "form-data@npm:4.0.4" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.8 + es-set-tostringtag: ^2.1.0 + hasown: ^2.0.2 + mime-types: ^2.1.12 + checksum: 9b7788836df9fa5a6999e0c02515b001946b2a868cfe53f026c69e2c537a2ff9fbfb8e9d2b678744628f3dc7a2d6e14e4e45dfaf68aa6239727f0bdb8ce0abf2 + languageName: node + linkType: hard + "fs-minipass@npm:^2.0.0": version: 2.1.0 resolution: "fs-minipass@npm:2.1.0" @@ -708,6 +1103,13 @@ __metadata: languageName: node linkType: hard +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 2b0ff4ce708d99715ad14a6d1f894e2a83242e4a52ccfcefaee5e40050562e5f6dafc1adbb4ce2d4ab47279a45dc736ab91ea5042d843c3c092820dfe032efb1 + languageName: node + linkType: hard + "gauge@npm:^4.0.3": version: 4.0.4 resolution: "gauge@npm:4.0.4" @@ -724,6 +1126,43 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.6": + version: 1.2.7 + resolution: "get-intrinsic@npm:1.2.7" + dependencies: + call-bind-apply-helpers: ^1.0.1 + es-define-property: ^1.0.1 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + function-bind: ^1.1.2 + get-proto: ^1.0.0 + gopd: ^1.2.0 + has-symbols: ^1.1.0 + hasown: ^2.0.2 + math-intrinsics: ^1.1.0 + checksum: a1597b3b432074f805b6a0ba1182130dd6517c0ea0c4eecc4b8834c803913e1ea62dfc412865be795b3dacb1555a21775b70cf9af7a18b1454ff3414e5442d4a + languageName: node + linkType: hard + +"get-proto@npm:^1.0.0": + version: 1.0.1 + resolution: "get-proto@npm:1.0.1" + dependencies: + dunder-proto: ^1.0.1 + es-object-atoms: ^1.0.0 + checksum: 4fc96afdb58ced9a67558698b91433e6b037aaa6f1493af77498d7c85b141382cf223c0e5946f334fb328ee85dfe6edd06d218eaf09556f4bc4ec6005d7f5f7b + languageName: node + linkType: hard + +"git-format-staged@npm:^2.1.3": + version: 2.1.3 + resolution: "git-format-staged@npm:2.1.3" + bin: + git-format-staged: git-format-staged + checksum: 749da68f0d9bf24db53b87a5f1613fc1a8790801d7c3ccb31d02b94d99f4cf2450126ef565f16adcc0649fbbf90dc44b4f009d4f99ff8a26921ba754bdb09b31 + languageName: node + linkType: hard + "glob@npm:^10.2.2": version: 10.3.3 resolution: "glob@npm:10.3.3" @@ -753,13 +1192,50 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.2.6": +"gopd@npm:^1.2.0": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: cc6d8e655e360955bdccaca51a12a474268f95bb793fc3e1f2bdadb075f28bfd1fd988dab872daf77a61d78cbaf13744bc8727a17cfb1d150d76047d805375f3 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 languageName: node linkType: hard +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 261a1357037ead75e338156b1f9452c016a37dcd3283a972a30d9e4a87441ba372c8b81f818cd0fbcd9c0354b4ae7e18b9e1afa1971164aef6d18c2b6095a8ad + languageName: node + linkType: hard + +"has-symbols@npm:^1.0.3": + version: 1.0.3 + resolution: "has-symbols@npm:1.0.3" + checksum: a054c40c631c0d5741a8285010a0777ea0c068f99ed43e5d6eb12972da223f8af553a455132fdb0801bdcfa0e0f443c0c03a68d8555aa529b3144b446c3f2410 + languageName: node + linkType: hard + +"has-symbols@npm:^1.1.0": + version: 1.1.0 + resolution: "has-symbols@npm:1.1.0" + checksum: b2316c7302a0e8ba3aaba215f834e96c22c86f192e7310bdf689dd0e6999510c89b00fbc5742571507cebf25764d68c988b3a0da217369a73596191ac0ce694b + languageName: node + linkType: hard + +"has-tostringtag@npm:^1.0.2": + version: 1.0.2 + resolution: "has-tostringtag@npm:1.0.2" + dependencies: + has-symbols: ^1.0.3 + checksum: 999d60bb753ad714356b2c6c87b7fb74f32463b8426e159397da4bde5bca7e598ab1073f4d8d4deafac297f2eb311484cd177af242776bf05f0d11565680468d + languageName: node + linkType: hard + "has-unicode@npm:^2.0.1": version: 2.0.1 resolution: "has-unicode@npm:2.0.1" @@ -767,6 +1243,15 @@ __metadata: languageName: node linkType: hard +"hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: ^1.1.2 + checksum: e8516f776a15149ca6c6ed2ae3110c417a00b62260e222590e54aa367cbcd6ed99122020b37b7fbdf05748df57b265e70095d7bf35a47660587619b15ffb93db + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.1.1": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" @@ -872,6 +1357,13 @@ __metadata: languageName: node linkType: hard +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 456ac6f8e0f3111ed34668a624e45315201dff921e5ac181f8ec24923b99e9f32ca1a194912dc79d539c97d33dba17dc635202ff0b2cf98326f608323276d27a + languageName: node + linkType: hard + "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -945,6 +1437,20 @@ __metadata: languageName: node linkType: hard +"js-sha256@npm:^0.9.0": + version: 0.9.0 + resolution: "js-sha256@npm:0.9.0" + checksum: ffad54b3373f81581e245866abfda50a62c483803a28176dd5c28fd2d313e0bdf830e77dac7ff8afd193c53031618920f3d98daf21cbbe80082753ab639c0365 + languageName: node + linkType: hard + +"js-sha3@npm:^0.8.0": + version: 0.8.0 + resolution: "js-sha3@npm:0.8.0" + checksum: 75df77c1fc266973f06cce8309ce010e9e9f07ec35ab12022ed29b7f0d9c8757f5a73e1b35aa24840dced0dea7059085aa143d817aea9e188e2a80d569d9adce + languageName: node + linkType: hard + "json-stringify-safe@npm:^5.0.1": version: 5.0.1 resolution: "json-stringify-safe@npm:5.0.1" @@ -1005,6 +1511,39 @@ __metadata: languageName: node linkType: hard +"math-intrinsics@npm:^1.1.0": + version: 1.1.0 + resolution: "math-intrinsics@npm:1.1.0" + checksum: 0e513b29d120f478c85a70f49da0b8b19bc638975eca466f2eeae0071f3ad00454c621bf66e16dd435896c208e719fc91ad79bbfba4e400fe0b372e7c1c9c9a2 + languageName: node + linkType: hard + +"micromatch@npm:^4.0.0": + version: 4.0.5 + resolution: "micromatch@npm:4.0.5" + dependencies: + braces: "npm:^3.0.2" + picomatch: "npm:^2.3.1" + checksum: 02a17b671c06e8fefeeb6ef996119c1e597c942e632a21ef589154f23898c9c6a9858526246abb14f8bca6e77734aa9dcf65476fca47cedfb80d9577d52843fc + languageName: node + linkType: hard + +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 0d99a03585f8b39d68182803b12ac601d9c01abfa28ec56204fa330bc9f3d1c5e14beb049bafadb3dbdf646dfb94b87e24d4ec7b31b7279ef906a8ea9b6a513f + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 89a5b7f1def9f3af5dad6496c5ed50191ae4331cc5389d7c521c8ad28d5fdad2d06fd81baf38fed813dc4e46bb55c8145bb0ff406330818c9cf712fb2e9b3836 + languageName: node + linkType: hard + "minimatch@npm:^3.1.1": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -1130,6 +1669,13 @@ __metadata: languageName: node linkType: hard +"multiformats@npm:^9.6.4": + version: 9.9.0 + resolution: "multiformats@npm:9.9.0" + checksum: d3e8c1be400c09a014f557ea02251a2710dbc9fca5aa32cc702ff29f636c5471e17979f30bdcb0a9cbb556f162a8591dc2e1219c24fc21394a56115b820bb84e + languageName: node + linkType: hard + "negotiator@npm:^0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" @@ -1224,6 +1770,13 @@ __metadata: languageName: node linkType: hard +"pako@npm:^2.0.3": + version: 2.1.0 + resolution: "pako@npm:2.1.0" + checksum: 71666548644c9a4d056bcaba849ca6fd7242c6cf1af0646d3346f3079a1c7f4a66ffec6f7369ee0dc88f61926c10d6ab05da3e1fca44b83551839e89edd75a3e + languageName: node + linkType: hard + "path-is-absolute@npm:^1.0.0": version: 1.0.1 resolution: "path-is-absolute@npm:1.0.1" @@ -1248,6 +1801,13 @@ __metadata: languageName: node linkType: hard +"picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf + languageName: node + linkType: hard + "promise-retry@npm:^2.0.1": version: 2.0.1 resolution: "promise-retry@npm:2.0.1" @@ -1258,6 +1818,13 @@ __metadata: languageName: node linkType: hard +"proxy-from-env@npm:^1.1.0": + version: 1.1.0 + resolution: "proxy-from-env@npm:1.1.0" + checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4 + languageName: node + linkType: hard + "readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" @@ -1349,7 +1916,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.5": +"semver@npm:^7.3.4, semver@npm:^7.3.5": version: 7.5.4 resolution: "semver@npm:7.5.4" dependencies: @@ -1490,6 +2057,13 @@ __metadata: languageName: node linkType: hard +"superstruct@npm:^0.15.4": + version: 0.15.5 + resolution: "superstruct@npm:0.15.5" + checksum: 6d1f5249fee789424b7178fa0a1ffb2ace629c5480c39505885bd8c0046a4ff8b267569a3442fa53b8c560a7ba6599cf3f8af94225aebeb2cf6023f7dd911050 + languageName: node + linkType: hard + "superstruct@npm:^2.0.2": version: 2.0.2 resolution: "superstruct@npm:2.0.2" @@ -1497,6 +2071,22 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 3dda818de06ebbe5b9653e07842d9479f3555ebc77e9a0280caf5a14fb877ffee9ed57007c3b78f5a6324b8dbeec648d9e97a24e2ed9fdb81ddc69ea07100f4a + languageName: node + linkType: hard + +"tapable@npm:^2.2.0": + version: 2.2.1 + resolution: "tapable@npm:2.2.1" + checksum: 3b7a1b4d86fa940aad46d9e73d1e8739335efd4c48322cb37d073eb6f80f5281889bf0320c6d8ffcfa1a0dd5bfdbd0f9d037e252ef972aca595330538aac4d51 + languageName: node + linkType: hard + "tar@npm:^6.1.11, tar@npm:^6.1.2": version: 6.1.15 resolution: "tar@npm:6.1.15" @@ -1525,6 +2115,22 @@ __metadata: languageName: node linkType: hard +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: f76fa01b3d5be85db6a2a143e24df9f60dd047d151062d0ba3df62953f2f697b16fe5dad9b0ac6191c7efc7b1d9dcaa4b768174b7b29da89d4428e64bc0a20ed + languageName: node + linkType: hard + +"toml@npm:^3.0.0": + version: 3.0.0 + resolution: "toml@npm:3.0.0" + checksum: 5d7f1d8413ad7780e9bdecce8ea4c3f5130dd53b0a4f2e90b93340979a137739879d7b9ce2ce05c938b8cc828897fe9e95085197342a1377dd8850bf5125f15f + languageName: node + linkType: hard + "tr46@npm:~0.0.3": version: 0.0.3 resolution: "tr46@npm:0.0.3" @@ -1532,6 +2138,21 @@ __metadata: languageName: node linkType: hard +"ts-loader@npm:^9.2.3": + version: 9.4.4 + resolution: "ts-loader@npm:9.4.4" + dependencies: + chalk: "npm:^4.1.0" + enhanced-resolve: "npm:^5.0.0" + micromatch: "npm:^4.0.0" + semver: "npm:^7.3.4" + peerDependencies: + typescript: "*" + webpack: ^5.0.0 + checksum: 8e5e6b839b0edfa40d2156c880d88ccab58226894ea5978221bc48c7db3215e2e856bfd0093f148e925a2befc42d6c94cafa9a994a7da274541efaa916012b63 + languageName: node + linkType: hard + "tslib@npm:^2.4.0": version: 2.6.2 resolution: "tslib@npm:2.6.2" @@ -1539,6 +2160,33 @@ __metadata: languageName: node linkType: hard +"typescript-collections@npm:^1.3.3": + version: 1.3.3 + resolution: "typescript-collections@npm:1.3.3" + checksum: a27f07dffdfe8407c4302eedb3e578b1360de783626cbd53519bd9c7943293a2940ed1ec3004cafae9dce049768b143185a36ca812d0d5c3c0f621a289239633 + languageName: node + linkType: hard + +"typescript@npm:^5.2.2": + version: 5.2.2 + resolution: "typescript@npm:5.2.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 7912821dac4d962d315c36800fe387cdc0a6298dba7ec171b350b4a6e988b51d7b8f051317786db1094bd7431d526b648aba7da8236607febb26cf5b871d2d3c + languageName: node + linkType: hard + +"typescript@patch:typescript@^5.2.2#~builtin": + version: 5.2.2 + resolution: "typescript@patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=f3b441" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 0f4da2f15e6f1245e49db15801dbee52f2bbfb267e1c39225afdab5afee1a72839cd86000e65ee9d7e4dfaff12239d28beaf5ee431357fcced15fb08583d72ca + languageName: node + linkType: hard + "unique-filename@npm:^3.0.0": version: 3.0.0 resolution: "unique-filename@npm:3.0.0" @@ -1700,3 +2348,10 @@ __metadata: checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5 languageName: node linkType: hard + +"zod@npm:^3.23.8": + version: 3.25.76 + resolution: "zod@npm:3.25.76" + checksum: c9a403a62b329188a5f6bd24d5d935d2bba345f7ab8151d1baa1505b5da9f227fb139354b043711490c798e91f3df75991395e40142e6510a4b16409f302b849 + languageName: node + linkType: hard diff --git a/packages/data-credits-sdk/package.json b/packages/data-credits-sdk/package.json index 030c47952..41419db71 100644 --- a/packages/data-credits-sdk/package.json +++ b/packages/data-credits-sdk/package.json @@ -37,6 +37,8 @@ "@helium/helium-sub-daos-sdk": "^0.10.35", "@helium/idls": "^0.10.35", "@helium/spl-utils": "^0.10.35", + "@pythnetwork/hermes-client": "^2.0.0", + "@pythnetwork/pyth-solana-receiver": "^0.10.2", "bn.js": "^5.2.0", "bs58": "^4.0.1" }, diff --git a/packages/data-credits-sdk/src/functions/mintDataCredits.ts b/packages/data-credits-sdk/src/functions/mintDataCredits.ts new file mode 100644 index 000000000..063072333 --- /dev/null +++ b/packages/data-credits-sdk/src/functions/mintDataCredits.ts @@ -0,0 +1,78 @@ +import { Program } from "@coral-xyz/anchor"; +import BN from "bn.js"; +import { DataCredits } from "@helium/idls/lib/types/data_credits"; +import { DC_MINT, HNT_PRICE_FEED_ID } from "@helium/spl-utils"; +import { InstructionWithEphemeralSigners, PythSolanaReceiver } from "@pythnetwork/pyth-solana-receiver"; +import { PublicKey } from "@solana/web3.js"; +import { HermesClient } from "@pythnetwork/hermes-client"; + +export const PYTH_HERMES_URL = "https://hermes.pyth.network/" + +export async function mintDataCredits({ + dcMint = DC_MINT, + dcAmount, + hntAmount, + program, + recipient, +}: { + dcMint?: PublicKey, + dcAmount?: BN, + hntAmount?: BN, + program: Program, + recipient?: PublicKey, +}) { + + if (!hntAmount && !dcAmount) { + throw new Error("Either hntAmount or dcAmount must be provided"); + } + + const priceServiceConnection = new HermesClient( + PYTH_HERMES_URL, + {} + ); + + const priceUpdates = ( + await priceServiceConnection.getLatestPriceUpdates( + [HNT_PRICE_FEED_ID], + { encoding: "base64" } + ) + ); + const priceUpdateData = priceUpdates.binary.data + + const wallet = program.provider.wallet + const connection = program.provider.connection + + // @ts-ignore + const pythSolanaReceiver = new PythSolanaReceiver({ connection, wallet: wallet! }); + + const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({ + closeUpdateAccounts: true, + }); + await transactionBuilder.addPostPriceUpdates(priceUpdateData); + + await transactionBuilder.addPriceConsumerInstructions( + async ( + getPriceUpdateAccount: (priceFeedId: string) => PublicKey + ): Promise => { + // Generate instructions here that use the price updates posted above. + // getPriceUpdateAccount() will give you the account for each price update. + return [{ + instruction: await program.methods + .mintDataCreditsV0({ + hntAmount: hntAmount ? hntAmount : null, + dcAmount: dcAmount ? dcAmount : null, + }) + .accountsPartial({ dcMint, hntPriceOracle: getPriceUpdateAccount(HNT_PRICE_FEED_ID), recipient }) + .instruction(), + signers: [], + }]; + } + ); + + return { + txs: await transactionBuilder.buildVersionedTransactions({ + computeUnitPriceMicroLamports: 10000, + }), + priceUpdates, + } +} \ No newline at end of file diff --git a/packages/data-credits-sdk/src/index.ts b/packages/data-credits-sdk/src/index.ts index fd4638aca..6db4ff9de 100644 --- a/packages/data-credits-sdk/src/index.ts +++ b/packages/data-credits-sdk/src/index.ts @@ -5,10 +5,11 @@ import { PROGRAM_ID } from "./constants"; import { dataCreditsResolvers } from "./resolvers"; import { fetchBackwardsCompatibleIdl } from "@helium/spl-utils"; - export * from "./constants"; export * from "./pdas"; +export { mintDataCredits } from "./functions/mintDataCredits"; + export async function init( provider: AnchorProvider, programId: PublicKey = PROGRAM_ID, diff --git a/packages/data-credits-sdk/yarn.deploy.lock b/packages/data-credits-sdk/yarn.deploy.lock index f0e30ee4b..0780f7ef7 100644 --- a/packages/data-credits-sdk/yarn.deploy.lock +++ b/packages/data-credits-sdk/yarn.deploy.lock @@ -5,6 +5,15 @@ __metadata: version: 6 cacheKey: 8 +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/runtime@npm:7.24.7" + dependencies: + regenerator-runtime: ^0.14.0 + checksum: d17f29eed6f848ac15cdf4202a910b741facfb0419a9d79e5c7fa37df6362fc3227f1cc2e248cc6db5e53ddffb4caa6686c488e6e80ce3d29c36a4e74c8734ea + languageName: node + linkType: hard + "@babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.22.6": version: 7.22.11 resolution: "@babel/runtime@npm:7.22.11" @@ -53,6 +62,28 @@ __metadata: languageName: node linkType: hard +"@coral-xyz/anchor@npm:^0.29.0": + version: 0.29.0 + resolution: "@coral-xyz/anchor@npm:0.29.0" + dependencies: + "@coral-xyz/borsh": ^0.29.0 + "@noble/hashes": ^1.3.1 + "@solana/web3.js": ^1.68.0 + bn.js: ^5.1.2 + bs58: ^4.0.1 + buffer-layout: ^1.2.2 + camelcase: ^6.3.0 + cross-fetch: ^3.1.5 + crypto-hash: ^1.3.0 + eventemitter3: ^4.0.7 + pako: ^2.0.3 + snake-case: ^3.0.4 + superstruct: ^0.15.4 + toml: ^3.0.0 + checksum: 10c4e6c5557653419683f5ae22ec47ac266b64e5b422d466885cf2dc7efa8f836239bdf321495d3e2b3ce03e766667c0e2192cc573fbd66bc12cc652f5146e10 + languageName: node + linkType: hard + "@coral-xyz/anchor@npm:^0.31.0": version: 0.31.0 resolution: "@coral-xyz/anchor@npm:0.31.0" @@ -86,6 +117,18 @@ __metadata: languageName: node linkType: hard +"@coral-xyz/borsh@npm:^0.29.0": + version: 0.29.0 + resolution: "@coral-xyz/borsh@npm:0.29.0" + dependencies: + bn.js: ^5.1.2 + buffer-layout: ^1.2.0 + peerDependencies: + "@solana/web3.js": ^1.68.0 + checksum: 37006c75cd012672adf48e10234062624634da2a9335e34b7ff30969f58aff78cc3073b66a3edc806b52f038469f0c477a5a3ed35aaa075f3cbd44d7133ac218 + languageName: node + linkType: hard + "@coral-xyz/borsh@npm:^0.31.0": version: 0.31.0 resolution: "@coral-xyz/borsh@npm:0.31.0" @@ -107,6 +150,30 @@ __metadata: languageName: node linkType: hard +"@grpc/grpc-js@npm:^1.8.13": + version: 1.10.9 + resolution: "@grpc/grpc-js@npm:1.10.9" + dependencies: + "@grpc/proto-loader": ^0.7.13 + "@js-sdsl/ordered-map": ^4.4.2 + checksum: 88d91c227175275d8cc178c807d09510a83d947911c9bfe8ccd132cb27144c54508bcd114d52ab00b6e4f37eecf74aeee3ef3971900bdb90735d55a0b0dba761 + languageName: node + linkType: hard + +"@grpc/proto-loader@npm:^0.7.13": + version: 0.7.13 + resolution: "@grpc/proto-loader@npm:0.7.13" + dependencies: + lodash.camelcase: ^4.3.0 + long: ^5.0.0 + protobufjs: ^7.2.5 + yargs: ^17.7.2 + bin: + proto-loader-gen-types: build/bin/proto-loader-gen-types.js + checksum: 399c1b8a4627f93dc31660d9636ea6bf58be5675cc7581e3df56a249369e5be02c6cd0d642c5332b0d5673bc8621619bc06fb045aa3e8f57383737b5d35930dc + languageName: node + linkType: hard + "@helium/account-fetch-cache@^0.10.35": version: 0.0.0-use.local resolution: "@helium/account-fetch-cache@workspace:packages/account-fetch-cache" @@ -170,6 +237,8 @@ __metadata: "@helium/helium-sub-daos-sdk": ^0.10.35 "@helium/idls": ^0.10.35 "@helium/spl-utils": ^0.10.35 + "@pythnetwork/hermes-client": ^2.0.0 + "@pythnetwork/pyth-solana-receiver": ^0.10.2 bn.js: ^5.2.0 bs58: ^4.0.1 git-format-staged: ^2.1.3 @@ -333,6 +402,13 @@ __metadata: languageName: node linkType: hard +"@js-sdsl/ordered-map@npm:^4.4.2": + version: 4.4.2 + resolution: "@js-sdsl/ordered-map@npm:4.4.2" + checksum: a927ae4ff8565ecb75355cc6886a4f8fadbf2af1268143c96c0cce3ba01261d241c3f4ba77f21f3f017a00f91dfe9e0673e95f830255945c80a0e96c6d30508a + languageName: node + linkType: hard + "@metaplex-foundation/beet-solana@npm:^0.4.0": version: 0.4.0 resolution: "@metaplex-foundation/beet-solana@npm:0.4.0" @@ -387,6 +463,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:^1.4.0": + version: 1.4.0 + resolution: "@noble/curves@npm:1.4.0" + dependencies: + "@noble/hashes": 1.4.0 + checksum: 0014ff561d16e98da4a57e2310a4015e4bdab3b1e1eafcd18d3f9b955c29c3501452ca5d702fddf8ca92d570bbeadfbe53fe16ebbd81a319c414f739154bb26b + languageName: node + linkType: hard + "@noble/curves@npm:^1.4.2": version: 1.8.0 resolution: "@noble/curves@npm:1.8.0" @@ -396,6 +481,13 @@ __metadata: languageName: node linkType: hard +"@noble/ed25519@npm:^1.7.1": + version: 1.7.3 + resolution: "@noble/ed25519@npm:1.7.3" + checksum: 45169927d51de513e47bbeebff3a603433c4ac7579e1b8c5034c380a0afedbe85e6959be3d69584a7a5ed6828d638f8f28879003b9bb2fb5f22d8aa2d88fd5fe + languageName: node + linkType: hard + "@noble/hashes@npm:1.3.2, @noble/hashes@npm:^1.3.1": version: 1.3.2 resolution: "@noble/hashes@npm:1.3.2" @@ -403,6 +495,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.3.0, @noble/hashes@npm:^1.4.0": + version: 1.4.0 + resolution: "@noble/hashes@npm:1.4.0" + checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 + languageName: node + linkType: hard + "@noble/hashes@npm:1.7.0": version: 1.7.0 resolution: "@noble/hashes@npm:1.7.0" @@ -410,13 +509,6 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:^1.4.0": - version: 1.4.0 - resolution: "@noble/hashes@npm:1.4.0" - checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 - languageName: node - linkType: hard - "@npmcli/fs@npm:^3.1.0": version: 3.1.0 resolution: "@npmcli/fs@npm:3.1.0" @@ -433,6 +525,125 @@ __metadata: languageName: node linkType: hard +"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/aspromise@npm:1.1.2" + checksum: 011fe7ef0826b0fd1a95935a033a3c0fd08483903e1aa8f8b4e0704e3233406abb9ee25350ec0c20bbecb2aad8da0dcea58b392bbd77d6690736f02c143865d2 + languageName: node + linkType: hard + +"@protobufjs/base64@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/base64@npm:1.1.2" + checksum: 67173ac34de1e242c55da52c2f5bdc65505d82453893f9b51dc74af9fe4c065cf4a657a4538e91b0d4a1a1e0a0642215e31894c31650ff6e3831471061e1ee9e + languageName: node + linkType: hard + +"@protobufjs/codegen@npm:^2.0.4": + version: 2.0.4 + resolution: "@protobufjs/codegen@npm:2.0.4" + checksum: 59240c850b1d3d0b56d8f8098dd04787dcaec5c5bd8de186fa548de86b86076e1c50e80144b90335e705a044edf5bc8b0998548474c2a10a98c7e004a1547e4b + languageName: node + linkType: hard + +"@protobufjs/eventemitter@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/eventemitter@npm:1.1.0" + checksum: 0369163a3d226851682f855f81413cbf166cd98f131edb94a0f67f79e75342d86e89df9d7a1df08ac28be2bc77e0a7f0200526bb6c2a407abbfee1f0262d5fd7 + languageName: node + linkType: hard + +"@protobufjs/fetch@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/fetch@npm:1.1.0" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.1" + "@protobufjs/inquire": "npm:^1.1.0" + checksum: 3fce7e09eb3f1171dd55a192066450f65324fd5f7cc01a431df01bb00d0a895e6bfb5b0c5561ce157ee1d886349c90703d10a4e11a1a256418ff591b969b3477 + languageName: node + linkType: hard + +"@protobufjs/float@npm:^1.0.2": + version: 1.0.2 + resolution: "@protobufjs/float@npm:1.0.2" + checksum: 5781e1241270b8bd1591d324ca9e3a3128d2f768077a446187a049e36505e91bc4156ed5ac3159c3ce3d2ba3743dbc757b051b2d723eea9cd367bfd54ab29b2f + languageName: node + linkType: hard + +"@protobufjs/inquire@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/inquire@npm:1.1.0" + checksum: ca06f02eaf65ca36fb7498fc3492b7fc087bfcc85c702bac5b86fad34b692bdce4990e0ef444c1e2aea8c034227bd1f0484be02810d5d7e931c55445555646f4 + languageName: node + linkType: hard + +"@protobufjs/path@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/path@npm:1.1.2" + checksum: 856eeb532b16a7aac071cacde5c5620df800db4c80cee6dbc56380524736205aae21e5ae47739114bf669ab5e8ba0e767a282ad894f3b5e124197cb9224445ee + languageName: node + linkType: hard + +"@protobufjs/pool@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/pool@npm:1.1.0" + checksum: d6a34fbbd24f729e2a10ee915b74e1d77d52214de626b921b2d77288bd8f2386808da2315080f2905761527cceffe7ec34c7647bd21a5ae41a25e8212ff79451 + languageName: node + linkType: hard + +"@protobufjs/utf8@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/utf8@npm:1.1.0" + checksum: f9bf3163d13aaa3b6f5e6fbf37a116e094ea021c0e1f2a7ccd0e12a29e2ce08dafba4e8b36e13f8ed7397e1591610ce880ed1289af4d66cf4ace8a36a9557278 + languageName: node + linkType: hard + +"@pythnetwork/hermes-client@npm:^2.0.0": + version: 2.0.0 + resolution: "@pythnetwork/hermes-client@npm:2.0.0" + dependencies: + "@zodios/core": ^10.9.6 + eventsource: ^3.0.5 + zod: ^3.23.8 + checksum: d5432c7c83617993a8e32fa4fde578e3b167ea348e5d3e2c681ee7bcf0e311824e00423d5529628f376f3541c888b9a12ed6c04135ea2e2f5872ab638a2dd31c + languageName: node + linkType: hard + +"@pythnetwork/price-service-sdk@npm:1.8.0": + version: 1.8.0 + resolution: "@pythnetwork/price-service-sdk@npm:1.8.0" + dependencies: + bn.js: ^5.2.1 + checksum: e843017db8469bc50c0e77b3db39c9756ff8d1c607a45626797ec4446121b9430770abcddcc15e08be132fa6081a5d872f0f79334cefceb7a1e7455300a1a426 + languageName: node + linkType: hard + +"@pythnetwork/pyth-solana-receiver@npm:^0.10.2": + version: 0.10.2 + resolution: "@pythnetwork/pyth-solana-receiver@npm:0.10.2" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@noble/hashes": ^1.4.0 + "@pythnetwork/price-service-sdk": 1.8.0 + "@pythnetwork/solana-utils": 0.4.5 + "@solana/web3.js": ^1.90.0 + checksum: 0b4376cb5c927d7571ca1b91216d47251a10aff52faf3d1581b8ac267facdb8214fedea7567e2266b2ba6f31cdb8ae44e6aa2ff7688f368c0582d4d59e89a287 + languageName: node + linkType: hard + +"@pythnetwork/solana-utils@npm:0.4.5": + version: 0.4.5 + resolution: "@pythnetwork/solana-utils@npm:0.4.5" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@solana/web3.js": ^1.90.0 + bs58: ^5.0.0 + jito-ts: ^3.0.1 + ts-log: ^2.2.7 + checksum: b877f2147a008403e13939b1b8e8a67d4d19432e46231b28c08d399010408093e9bad553ea2a7d7640496e37f1feac3e9fc01b8895f61c2d2617226a0d92d61e + languageName: node + linkType: hard + "@solana/buffer-layout-utils@npm:^0.2.0": version: 0.2.0 resolution: "@solana/buffer-layout-utils@npm:0.2.0" @@ -529,6 +740,52 @@ __metadata: languageName: node linkType: hard +"@solana/web3.js@npm:^1.90.0": + version: 1.93.0 + resolution: "@solana/web3.js@npm:1.93.0" + dependencies: + "@babel/runtime": ^7.24.7 + "@noble/curves": ^1.4.0 + "@noble/hashes": ^1.4.0 + "@solana/buffer-layout": ^4.0.1 + agentkeepalive: ^4.5.0 + bigint-buffer: ^1.1.5 + bn.js: ^5.2.1 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.0 + node-fetch: ^2.7.0 + rpc-websockets: ^9.0.0 + superstruct: ^1.0.4 + checksum: 3ae7d1e0cd998481b0d17076aec5df8c8593e7a9927ea245db19b18473abe3c96b94553de1f130ae1662a65a57b372a49025da38eeec598eb6c8ef355891b8b4 + languageName: node + linkType: hard + +"@solana/web3.js@npm:~1.77.3": + version: 1.77.4 + resolution: "@solana/web3.js@npm:1.77.4" + dependencies: + "@babel/runtime": ^7.12.5 + "@noble/curves": ^1.0.0 + "@noble/hashes": ^1.3.0 + "@solana/buffer-layout": ^4.0.0 + agentkeepalive: ^4.2.1 + bigint-buffer: ^1.1.5 + bn.js: ^5.0.0 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.0 + node-fetch: ^2.6.7 + rpc-websockets: ^7.5.1 + superstruct: ^0.14.2 + checksum: 7cd705244e83e74500ec3493b5d1743cc2c7d966c5775847baae356102602f65d35c5a2d9bca9a898bea0d05df057002b5c7660b9543ce7a8457442a20f24406 + languageName: node + linkType: hard + "@swc/helpers@npm:^0.5.11": version: 0.5.11 resolution: "@swc/helpers@npm:0.5.11" @@ -582,7 +839,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*": +"@types/node@npm:*, @types/node@npm:>=13.7.0": version: 20.5.7 resolution: "@types/node@npm:20.5.7" checksum: fc284c8e16ddc04569730d58e87eae349eb1c3dd9020cb79a1862d9d9add6f04e7367a236f3252db8db2572f90278e250f4cd43d27d264972b54394eaba1ed76 @@ -621,6 +878,16 @@ __metadata: languageName: node linkType: hard +"@zodios/core@npm:^10.9.6": + version: 10.9.6 + resolution: "@zodios/core@npm:10.9.6" + peerDependencies: + axios: ^0.x || ^1.0.0 + zod: ^3.x + checksum: 482a80bd4da661734f9ed276a92d9275fa1b76011bef26ede4a851e4c495d9103e6c9456074b9e50e4c89ad7e83fcead6ea45ffba615e6ff54b8088433ba47fc + languageName: node + linkType: hard + "JSONStream@npm:^1.3.5": version: 1.3.5 resolution: "JSONStream@npm:1.3.5" @@ -819,7 +1086,7 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": +"bn.js@npm:^5.0.0, bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": version: 5.2.1 resolution: "bn.js@npm:5.2.1" checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 @@ -971,6 +1238,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^8.0.1": + version: 8.0.1 + resolution: "cliui@npm:8.0.1" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^7.0.0" + checksum: 79648b3b0045f2e285b76fb2e24e207c6db44323581e421c3acbd0e86454cba1b37aea976ab50195a49e7384b871e6dfb2247ad7dec53c02454ac6497394cb56 + languageName: node + linkType: hard + "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -1110,6 +1388,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^16.0.3": + version: 16.3.1 + resolution: "dotenv@npm:16.3.1" + checksum: 15d75e7279018f4bafd0ee9706593dd14455ddb71b3bcba9c52574460b7ccaf67d5cf8b2c08a5af1a9da6db36c956a04a1192b101ee102a3e0cf8817bbcf3dfd + languageName: node + linkType: hard + "dunder-proto@npm:^1.0.1": version: 1.0.1 resolution: "dunder-proto@npm:1.0.1" @@ -1226,6 +1511,13 @@ __metadata: languageName: node linkType: hard +"escalade@npm:^3.1.1": + version: 3.1.1 + resolution: "escalade@npm:3.1.1" + checksum: a3e2a99f07acb74b3ad4989c48ca0c3140f69f923e56d0cba0526240ee470b91010f9d39001f2a4a313841d237ede70a729e92125191ba5d21e74b106800b133 + languageName: node + linkType: hard + "eventemitter3@npm:^4.0.7": version: 4.0.7 resolution: "eventemitter3@npm:4.0.7" @@ -1240,6 +1532,22 @@ __metadata: languageName: node linkType: hard +"eventsource-parser@npm:^3.0.1": + version: 3.0.3 + resolution: "eventsource-parser@npm:3.0.3" + checksum: a052aaedb89da8744219aea539343dabc54c6e032acc47f182a90fbbb083583208fbe0f786d7bc1182da098c88a391b7881b59a3fc921a73b718f25d1ee37425 + languageName: node + linkType: hard + +"eventsource@npm:^3.0.5": + version: 3.0.7 + resolution: "eventsource@npm:3.0.7" + dependencies: + eventsource-parser: ^3.0.1 + checksum: cd8cbc3418238b9d751b6652edf442d4b869829fbc3b73444abca1816fe3d23dc707130dd9a990360bc27c281d986f2f62059d870921173425c3ac28d20a8414 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -1358,6 +1666,13 @@ __metadata: languageName: node linkType: hard +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 + languageName: node + linkType: hard + "get-intrinsic@npm:^1.2.6": version: 1.2.7 resolution: "get-intrinsic@npm:1.2.7" @@ -1625,7 +1940,7 @@ __metadata: languageName: node linkType: hard -"jayson@npm:^4.1.0": +"jayson@npm:^4.0.0, jayson@npm:^4.1.0": version: 4.1.0 resolution: "jayson@npm:4.1.0" dependencies: @@ -1669,6 +1984,22 @@ __metadata: languageName: node linkType: hard +"jito-ts@npm:^3.0.1": + version: 3.0.1 + resolution: "jito-ts@npm:3.0.1" + dependencies: + "@grpc/grpc-js": ^1.8.13 + "@noble/ed25519": ^1.7.1 + "@solana/web3.js": ~1.77.3 + agentkeepalive: ^4.3.0 + dotenv: ^16.0.3 + jayson: ^4.0.0 + node-fetch: ^2.6.7 + superstruct: ^1.0.3 + checksum: bdacbba32601be1e1b6a9a96c9cf9ba6c16fc265da5f936295146099c3e86205ef46d67e771545452c1213a48de5008fcd3ce41c786afce03586d583a00f9319 + languageName: node + linkType: hard + "js-sha256@npm:^0.9.0": version: 0.9.0 resolution: "js-sha256@npm:0.9.0" @@ -1697,6 +2028,20 @@ __metadata: languageName: node linkType: hard +"lodash.camelcase@npm:^4.3.0": + version: 4.3.0 + resolution: "lodash.camelcase@npm:4.3.0" + checksum: cb9227612f71b83e42de93eccf1232feeb25e705bdb19ba26c04f91e885bfd3dd5c517c4a97137658190581d3493ea3973072ca010aab7e301046d90740393d1 + languageName: node + linkType: hard + +"long@npm:^5.0.0": + version: 5.2.3 + resolution: "long@npm:5.2.3" + checksum: 885ede7c3de4facccbd2cacc6168bae3a02c3e836159ea4252c87b6e34d40af819824b2d4edce330bfb5c4d6e8ce3ec5864bdcf9473fa1f53a4f8225860e5897 + languageName: node + linkType: hard + "lower-case@npm:^2.0.2": version: 2.0.2 resolution: "lower-case@npm:2.0.2" @@ -1941,7 +2286,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.12, node-fetch@npm:^2.7.0": +"node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.7, node-fetch@npm:^2.7.0": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -2076,6 +2421,26 @@ __metadata: languageName: node linkType: hard +"protobufjs@npm:^7.2.5": + version: 7.3.2 + resolution: "protobufjs@npm:7.3.2" + dependencies: + "@protobufjs/aspromise": ^1.1.2 + "@protobufjs/base64": ^1.1.2 + "@protobufjs/codegen": ^2.0.4 + "@protobufjs/eventemitter": ^1.1.0 + "@protobufjs/fetch": ^1.1.0 + "@protobufjs/float": ^1.0.2 + "@protobufjs/inquire": ^1.1.0 + "@protobufjs/path": ^1.1.2 + "@protobufjs/pool": ^1.1.0 + "@protobufjs/utf8": ^1.1.0 + "@types/node": ">=13.7.0" + long: ^5.0.0 + checksum: cfb2a744787f26ee7c82f3e7c4b72cfc000e9bb4c07828ed78eb414db0ea97a340c0cc3264d0e88606592f847b12c0351411f10e9af255b7ba864eec44d7705f + languageName: node + linkType: hard + "proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" @@ -2101,6 +2466,13 @@ __metadata: languageName: node linkType: hard +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: fb47e70bf0001fdeabdc0429d431863e9475e7e43ea5f94ad86503d918423c1543361cc5166d713eaa7029dd7a3d34775af04764bebff99ef413111a5af18c80 + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -2138,6 +2510,28 @@ __metadata: languageName: node linkType: hard +"rpc-websockets@npm:^9.0.0": + version: 9.0.1 + resolution: "rpc-websockets@npm:9.0.1" + dependencies: + "@swc/helpers": ^0.5.11 + "@types/uuid": ^8.3.4 + "@types/ws": ^8.2.2 + buffer: ^6.0.3 + bufferutil: ^4.0.1 + eventemitter3: ^5.0.1 + utf-8-validate: ^5.0.2 + uuid: ^8.3.2 + ws: ^8.5.0 + dependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: f268741ca904b7ab0845188a8cadd61b6872228a76eb3cedcd96be9bd8b9a3fab9113b0ff9a9c2a85179fa337cb52b1d48bdaeb21ff46bc71cdaae20cf80dc3b + languageName: node + linkType: hard + "rpc-websockets@npm:^9.0.2": version: 9.0.4 resolution: "rpc-websockets@npm:9.0.4" @@ -2269,7 +2663,7 @@ __metadata: languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.3": +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -2332,6 +2726,13 @@ __metadata: languageName: node linkType: hard +"superstruct@npm:^1.0.3, superstruct@npm:^1.0.4": + version: 1.0.4 + resolution: "superstruct@npm:1.0.4" + checksum: 2e070994cc4998a753c3f0215449d6de01ffb8180e4f46527f559ffbc2ebcc40fcf428f545ccd355921ef2920db7d138a96258ae35c788e6c24b2aa8bb1695cb + languageName: node + linkType: hard + "superstruct@npm:^2.0.2": version: 2.0.2 resolution: "superstruct@npm:2.0.2" @@ -2421,6 +2822,13 @@ __metadata: languageName: node linkType: hard +"ts-log@npm:^2.2.7": + version: 2.2.7 + resolution: "ts-log@npm:2.2.7" + checksum: c423a5eb54abb9471578902953814d3d0c88b3f237db016998f8998ecf982cb0f748bb8ebf93670eeba9b836ff0ce407d8065a340f3ab218ea7b9442c255b3d4 + languageName: node + linkType: hard + "ts-node@npm:^10.9.1": version: 10.9.1 resolution: "ts-node@npm:10.9.1" @@ -2581,7 +2989,7 @@ __metadata: languageName: node linkType: hard -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" dependencies: @@ -2655,6 +3063,13 @@ __metadata: languageName: node linkType: hard +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 54f0fb95621ee60898a38c572c515659e51cc9d9f787fb109cef6fde4befbe1c4602dc999d30110feee37456ad0f1660fa2edcfde6a9a740f86a290999550d30 + languageName: node + linkType: hard + "yallist@npm:^4.0.0": version: 4.0.0 resolution: "yallist@npm:4.0.0" @@ -2662,9 +3077,38 @@ __metadata: languageName: node linkType: hard +"yargs-parser@npm:^21.1.1": + version: 21.1.1 + resolution: "yargs-parser@npm:21.1.1" + checksum: ed2d96a616a9e3e1cc7d204c62ecc61f7aaab633dcbfab2c6df50f7f87b393993fe6640d017759fe112d0cb1e0119f2b4150a87305cc873fd90831c6a58ccf1c + languageName: node + linkType: hard + +"yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: "npm:^8.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.3" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^21.1.1" + checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a + languageName: node + linkType: hard + "yn@npm:3.1.1": version: 3.1.1 resolution: "yn@npm:3.1.1" checksum: 2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6 languageName: node linkType: hard + +"zod@npm:^3.23.8": + version: 3.25.76 + resolution: "zod@npm:3.25.76" + checksum: c9a403a62b329188a5f6bd24d5d935d2bba345f7ab8151d1baa1505b5da9f227fb139354b043711490c798e91f3df75991395e40142e6510a4b16409f302b849 + languageName: node + linkType: hard diff --git a/packages/distributor-oracle/Dockerfile b/packages/distributor-oracle/Dockerfile index d8ee21c1e..52411d343 100644 --- a/packages/distributor-oracle/Dockerfile +++ b/packages/distributor-oracle/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/entity-invalidator/Dockerfile b/packages/entity-invalidator/Dockerfile index 808f0fcb4..49b6c607c 100644 --- a/packages/entity-invalidator/Dockerfile +++ b/packages/entity-invalidator/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/fanout-metadata-service/Dockerfile b/packages/fanout-metadata-service/Dockerfile index 2a9fe34c3..0fd7a7dde 100644 --- a/packages/fanout-metadata-service/Dockerfile +++ b/packages/fanout-metadata-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/faucet-service/Dockerfile b/packages/faucet-service/Dockerfile index 2a9fe34c3..0fd7a7dde 100644 --- a/packages/faucet-service/Dockerfile +++ b/packages/faucet-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/helium-admin-cli/src/create-dao.ts b/packages/helium-admin-cli/src/create-dao.ts index f8eb7d9b5..8546acff9 100644 --- a/packages/helium-admin-cli/src/create-dao.ts +++ b/packages/helium-admin-cli/src/create-dao.ts @@ -118,7 +118,7 @@ export async function run(args: any = process.argv) { type: "string", describe: "Bucket URL prefix holding all of the metadata jsons", default: - "https://shdw-drive.genesysgo.net/6tcnBSybPG7piEDShBcrVtYJDPSvGrDbVvXmXKpzBvWP", + "https://entities.nft.helium.io/v2/tokens", }, emissionSchedulePath: { required: true, @@ -170,10 +170,6 @@ export async function run(args: any = process.argv) { describe: "Authority index for squads. Defaults to 1", default: 1, }, - hntPriceOracle: { - type: "string", - required: true, - }, rewardsOracleUrl: { alias: "ro", type: "string", @@ -270,7 +266,7 @@ export async function run(args: any = process.argv) { provider, mintKeypair: hntKeypair, amount: argv.numHnt, - metadataUrl: `${argv.bucket}/hnt.json`, + metadataUrl: `${argv.bucket}/hnt`, updateAuthority: authority, }); @@ -279,27 +275,11 @@ export async function run(args: any = process.argv) { mintKeypair: dcKeypair, amount: argv.numDc, decimals: 0, - metadataUrl: `${argv.bucket}/dc.json`, - updateAuthority: authority, - }); - - await createAndMint({ - provider, - mintKeypair: councilKeypair, - amount: argv.numCouncil, - decimals: 0, - metadataUrl: `${argv.bucket}/council.json`, - to: councilWallet, + metadataUrl: `${argv.bucket}/dc`, updateAuthority: authority, }); let instructions: TransactionInstruction[] = []; - const govProgramVersion = await getGovernanceProgramVersion( - conn, - govProgramId, - isLocalhost(provider) ? "localnet" : undefined - ); - const delProgram = await init(provider); const { pubkeys: { proxyConfig }, @@ -328,36 +308,6 @@ export async function run(args: any = process.argv) { )[0]; console.log("Realm, ", realm.toBase58()); - const needRealmCreate = !(await exists(conn, realm)); - if (needRealmCreate) { - console.log("Initializing Realm"); - await withCreateRealm( - instructions, - govProgramId, - govProgramVersion, - realmName, - provider.wallet.publicKey, // realmAuthorityPk - hntKeypair.publicKey, // communityMintPk - provider.wallet.publicKey, // payer - councilKeypair.publicKey, // councilMintPk - MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION, - new anchor.BN(1000000000000000), // 10mm vehnt to create governance. Council should be the only one doing this - new GoverningTokenConfigAccountArgs({ - // community token config - voterWeightAddin: heliumVsrProgram.programId, - maxVoterWeightAddin: heliumVsrProgram.programId, - tokenType: GoverningTokenType.Liquid, - }), - new GoverningTokenConfigAccountArgs({ - // council token config - voterWeightAddin: undefined, - maxVoterWeightAddin: undefined, - tokenType: GoverningTokenType.Liquid, - }) - ); - await sendInstructions(provider, instructions, []); - instructions = []; - } const registrar = (await registrarKey(realm, hntKeypair.publicKey))[0]; if (!(await exists(conn, registrar))) { @@ -413,17 +363,6 @@ export async function run(args: any = process.argv) { await sendInstructions(provider, instructions, []); instructions = []; - if (needRealmCreate && !authority.equals(me)) { - withSetRealmAuthority( - instructions, - govProgramId, - govProgramVersion, - realm, - provider.wallet.publicKey, - authority, - SetRealmAuthorityAction.SetUnchecked - ); - } await sendInstructions(provider, instructions, []); instructions = []; @@ -442,7 +381,6 @@ export async function run(args: any = process.argv) { .accountsPartial({ hntMint: hntKeypair.publicKey, dcMint: dcKeypair.publicKey, - hntPriceOracle: new PublicKey(argv.hntPriceOracle), }) .rpc({ skipPreflight: true }); diff --git a/packages/helium-admin-cli/src/create-subdao.ts b/packages/helium-admin-cli/src/create-subdao.ts index ce21e3696..490ff9dd0 100644 --- a/packages/helium-admin-cli/src/create-subdao.ts +++ b/packages/helium-admin-cli/src/create-subdao.ts @@ -4,7 +4,6 @@ import { init as initHem, rewardableEntityConfigKey, } from "@helium/helium-entity-manager-sdk"; -import fs from "fs"; import { daoKey, init as initDao, @@ -15,6 +14,7 @@ import { init as initLazy, lazyDistributorKey, } from "@helium/lazy-distributor-sdk"; +import { init } from "@helium/nft-proxy-sdk"; import { oracleSignerKey } from "@helium/rewards-oracle-sdk"; import { sendInstructions, toBN } from "@helium/spl-utils"; import { toU128 } from "@helium/treasury-management-sdk"; @@ -23,13 +23,7 @@ import { registrarKey, } from "@helium/voter-stake-registry-sdk"; import { - getGovernanceProgramVersion, - GoverningTokenConfigAccountArgs, - GoverningTokenType, - MintMaxVoteWeightSource, - SetRealmAuthorityAction, - withCreateRealm, - withSetRealmAuthority, + getGovernanceProgramVersion } from "@solana/spl-governance"; import { getAssociatedTokenAddress } from "@solana/spl-token"; import { @@ -39,6 +33,8 @@ import { TransactionInstruction, } from "@solana/web3.js"; import Squads from "@sqds/sdk"; +import BN from "bn.js"; +import fs from "fs"; import os from "os"; import yargs from "yargs/yargs"; import { @@ -50,8 +46,6 @@ import { parseEmissionsSchedule, sendInstructionsOrSquads, } from "./utils"; -import { init } from "@helium/nft-proxy-sdk"; -import BN from "bn.js" const SECS_PER_DAY = 86400; const SECS_PER_YEAR = 365 * SECS_PER_DAY; @@ -112,7 +106,7 @@ export async function run(args: any = process.argv) { type: "string", describe: "Bucket URL prefix holding all of the metadata jsons", default: - "https://shdw-drive.genesysgo.net/6tcnBSybPG7piEDShBcrVtYJDPSvGrDbVvXmXKpzBvWP", + "https://entities.nft.helium.io/v2/tokens", }, rewardsOracleUrl: { alias: "ro", @@ -158,11 +152,6 @@ export async function run(args: any = process.argv) { describe: "Pubkey of the GOV program", default: "hgovkRU6Ghe1Qoyb54HdSLdqN7VtxaifBzRmh9jtd3S", }, - councilKeypair: { - type: "string", - describe: "Keypair of gov council token", - default: `${__dirname}/../../keypairs/council.json`, - }, multisig: { type: "string", describe: @@ -212,12 +201,10 @@ export async function run(args: any = process.argv) { const oracleKey = oracleKeypair.publicKey; const rewardsOracleUrl = argv.rewardsOracleUrl; const govProgramId = new PublicKey(argv.govProgramId); - const councilKeypair = await loadKeypair(argv.councilKeypair); const me = provider.wallet.publicKey; console.log("Subdao mint", subdaoKeypair.publicKey.toBase58()); console.log("GOV PID", govProgramId.toBase58()); - console.log("COUNCIL", councilKeypair.publicKey.toBase58()); const conn = provider.connection; @@ -277,7 +264,7 @@ export async function run(args: any = process.argv) { mintKeypair: subdaoKeypair, amount: argv.numTokens, decimals: argv.decimals, - metadataUrl: `${argv.bucket}/${name.toLowerCase()}.json`, + metadataUrl: `${argv.bucket}/${name.toLowerCase()}`, mintAuthority: daoAcc.authority, freezeAuthority: daoAcc.authority, updateAuthority: authority, @@ -317,36 +304,6 @@ export async function run(args: any = process.argv) { govProgramId )[0]; console.log("Realm, ", realm.toBase58()); - const isFreshRealm = !(await exists(conn, realm)); - if (isFreshRealm) { - console.log("Initializing Realm"); - await withCreateRealm( - instructions, - govProgramId, - govProgramVersion, - realmName, - provider.wallet.publicKey, // realmAuthorityPk - subdaoKeypair.publicKey, // communityMintPk - provider.wallet.publicKey, // payer - councilKeypair.publicKey, // councilMintPk - MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION, - new anchor.BN(1000000000000000), // 10mm vehnt to create governance. Council should be the only one doing this - new GoverningTokenConfigAccountArgs({ - // community token config - voterWeightAddin: heliumVsrProgram.programId, - maxVoterWeightAddin: heliumVsrProgram.programId, - tokenType: GoverningTokenType.Liquid, - }), - new GoverningTokenConfigAccountArgs({ - // council token config - voterWeightAddin: undefined, - maxVoterWeightAddin: undefined, - tokenType: GoverningTokenType.Liquid, - }) - ); - await sendInstructions(provider, instructions, []); - instructions = []; - } const registrar = (await registrarKey(realm, subdaoKeypair.publicKey))[0]; if (!(await exists(conn, registrar))) { @@ -394,21 +351,6 @@ export async function run(args: any = process.argv) { instructions = []; } - await sendInstructions(provider, instructions, []); - instructions = []; - - if (isFreshRealm && !authority.equals(me)) { - withSetRealmAuthority( - instructions, - govProgramId, - govProgramVersion, - realm, - provider.wallet.publicKey, - daoAcc.authority, - SetRealmAuthorityAction.SetUnchecked - ); - } - await sendInstructions(provider, instructions, []); if (!(await exists(conn, lazyDist))) { diff --git a/packages/helium-admin-cli/src/mint-dc.ts b/packages/helium-admin-cli/src/mint-dc.ts index 9c0061f81..efecba1c1 100644 --- a/packages/helium-admin-cli/src/mint-dc.ts +++ b/packages/helium-admin-cli/src/mint-dc.ts @@ -1,5 +1,5 @@ -import { init as initDc } from "@helium/data-credits-sdk"; -import { toBN, DC_MINT } from "@helium/spl-utils"; +import { init as initDc, mintDataCredits } from "@helium/data-credits-sdk"; +import { toBN, DC_MINT, sendInstructions } from "@helium/spl-utils"; import * as anchor from "@coral-xyz/anchor"; import { createAssociatedTokenAccountIdempotent, createAssociatedTokenAccountIdempotentInstruction, getAssociatedTokenAddress, getAssociatedTokenAddressSync } from "@solana/spl-token"; import { PublicKey } from "@solana/web3.js"; @@ -57,25 +57,24 @@ export async function run(args: any = process.argv) { throw e; } } + + await sendInstructions(provider, [ + await createAssociatedTokenAccountIdempotentInstruction( + provider.wallet.publicKey, + getAssociatedTokenAddressSync(dcKey, destination, true), + destination, + dcKey + ) + ]) + const {txs} = await mintDataCredits({ + program: dataCreditsProgram, + hntAmount: toBN(argv.numHnt, 8), + dcMint: dcKey, + recipient: destination, + }) + + await provider.sendAll(txs) - await dataCreditsProgram.methods - .mintDataCreditsV0({ - hntAmount: toBN(argv.numHnt, 8), - dcAmount: null - }) - .preInstructions([ - await createAssociatedTokenAccountIdempotentInstruction( - provider.wallet.publicKey, - getAssociatedTokenAddressSync(dcKey, destination, true), - destination, - dcKey - ) - ]) - .accountsPartial({ - dcMint: dcKey, - recipient: destination, - }) - .rpc({ skipPreflight: true }); const postBalance = ( await provider.connection.getTokenAccountBalance(destAta, "confirmed") ).value.uiAmount; diff --git a/packages/helium-admin-cli/src/update-data-credits.ts b/packages/helium-admin-cli/src/update-data-credits.ts index 5a6655665..04c5f0af2 100644 --- a/packages/helium-admin-cli/src/update-data-credits.ts +++ b/packages/helium-admin-cli/src/update-data-credits.ts @@ -30,9 +30,6 @@ export async function run(args: any = process.argv) { newAuthority: { type: 'string', }, - hntPriceOracle: { - type: 'string', - }, executeTransaction: { type: 'boolean', }, @@ -68,9 +65,6 @@ export async function run(args: any = process.argv) { newAuthority: argv.newAuthority ? new PublicKey(argv.newAuthority) : null, - hntPriceOracle: argv.hntPriceOracle - ? new PublicKey(argv.hntPriceOracle) - : null, }) .accountsPartial({ dataCredits, diff --git a/packages/helium-admin-cli/yarn.deploy.lock b/packages/helium-admin-cli/yarn.deploy.lock index d884b376f..aaf97bddd 100644 --- a/packages/helium-admin-cli/yarn.deploy.lock +++ b/packages/helium-admin-cli/yarn.deploy.lock @@ -14,6 +14,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/runtime@npm:7.24.7" + dependencies: + regenerator-runtime: ^0.14.0 + checksum: d17f29eed6f848ac15cdf4202a910b741facfb0419a9d79e5c7fa37df6362fc3227f1cc2e248cc6db5e53ddffb4caa6686c488e6e80ce3d29c36a4e74c8734ea + languageName: node + linkType: hard + "@babel/runtime@npm:^7.25.0": version: 7.26.0 resolution: "@babel/runtime@npm:7.26.0" @@ -76,6 +85,28 @@ __metadata: languageName: node linkType: hard +"@coral-xyz/anchor@npm:^0.29.0": + version: 0.29.0 + resolution: "@coral-xyz/anchor@npm:0.29.0" + dependencies: + "@coral-xyz/borsh": ^0.29.0 + "@noble/hashes": ^1.3.1 + "@solana/web3.js": ^1.68.0 + bn.js: ^5.1.2 + bs58: ^4.0.1 + buffer-layout: ^1.2.2 + camelcase: ^6.3.0 + cross-fetch: ^3.1.5 + crypto-hash: ^1.3.0 + eventemitter3: ^4.0.7 + pako: ^2.0.3 + snake-case: ^3.0.4 + superstruct: ^0.15.4 + toml: ^3.0.0 + checksum: 10c4e6c5557653419683f5ae22ec47ac266b64e5b422d466885cf2dc7efa8f836239bdf321495d3e2b3ce03e766667c0e2192cc573fbd66bc12cc652f5146e10 + languageName: node + linkType: hard + "@coral-xyz/anchor@npm:^0.31.0": version: 0.31.0 resolution: "@coral-xyz/anchor@npm:0.31.0" @@ -121,6 +152,18 @@ __metadata: languageName: node linkType: hard +"@coral-xyz/borsh@npm:^0.29.0": + version: 0.29.0 + resolution: "@coral-xyz/borsh@npm:0.29.0" + dependencies: + bn.js: ^5.1.2 + buffer-layout: ^1.2.0 + peerDependencies: + "@solana/web3.js": ^1.68.0 + checksum: 37006c75cd012672adf48e10234062624634da2a9335e34b7ff30969f58aff78cc3073b66a3edc806b52f038469f0c477a5a3ed35aaa075f3cbd44d7133ac218 + languageName: node + linkType: hard + "@coral-xyz/borsh@npm:^0.31.0": version: 0.31.0 resolution: "@coral-xyz/borsh@npm:0.31.0" @@ -195,6 +238,30 @@ __metadata: languageName: node linkType: hard +"@grpc/grpc-js@npm:^1.8.13": + version: 1.10.9 + resolution: "@grpc/grpc-js@npm:1.10.9" + dependencies: + "@grpc/proto-loader": ^0.7.13 + "@js-sdsl/ordered-map": ^4.4.2 + checksum: 88d91c227175275d8cc178c807d09510a83d947911c9bfe8ccd132cb27144c54508bcd114d52ab00b6e4f37eecf74aeee3ef3971900bdb90735d55a0b0dba761 + languageName: node + linkType: hard + +"@grpc/proto-loader@npm:^0.7.13": + version: 0.7.13 + resolution: "@grpc/proto-loader@npm:0.7.13" + dependencies: + lodash.camelcase: ^4.3.0 + long: ^5.0.0 + protobufjs: ^7.2.5 + yargs: ^17.7.2 + bin: + proto-loader-gen-types: build/bin/proto-loader-gen-types.js + checksum: 399c1b8a4627f93dc31660d9636ea6bf58be5675cc7581e3df56a249369e5be02c6cd0d642c5332b0d5673bc8621619bc06fb045aa3e8f57383737b5d35930dc + languageName: node + linkType: hard + "@helium/account-fetch-cache@^0.10.35": version: 0.0.0-use.local resolution: "@helium/account-fetch-cache@workspace:packages/account-fetch-cache" @@ -293,6 +360,8 @@ __metadata: "@helium/helium-sub-daos-sdk": ^0.10.35 "@helium/idls": ^0.10.35 "@helium/spl-utils": ^0.10.35 + "@pythnetwork/hermes-client": ^2.0.0 + "@pythnetwork/pyth-solana-receiver": ^0.10.2 bn.js: ^5.2.0 bs58: ^4.0.1 git-format-staged: ^2.1.3 @@ -795,6 +864,13 @@ __metadata: languageName: node linkType: hard +"@js-sdsl/ordered-map@npm:^4.4.2": + version: 4.4.2 + resolution: "@js-sdsl/ordered-map@npm:4.4.2" + checksum: a927ae4ff8565ecb75355cc6886a4f8fadbf2af1268143c96c0cce3ba01261d241c3f4ba77f21f3f017a00f91dfe9e0673e95f830255945c80a0e96c6d30508a + languageName: node + linkType: hard + "@metaplex-foundation/beet-solana@npm:0.4.0, @metaplex-foundation/beet-solana@npm:^0.4.0": version: 0.4.0 resolution: "@metaplex-foundation/beet-solana@npm:0.4.0" @@ -865,6 +941,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:^1.4.0": + version: 1.4.0 + resolution: "@noble/curves@npm:1.4.0" + dependencies: + "@noble/hashes": 1.4.0 + checksum: 0014ff561d16e98da4a57e2310a4015e4bdab3b1e1eafcd18d3f9b955c29c3501452ca5d702fddf8ca92d570bbeadfbe53fe16ebbd81a319c414f739154bb26b + languageName: node + linkType: hard + "@noble/curves@npm:^1.4.2": version: 1.8.0 resolution: "@noble/curves@npm:1.8.0" @@ -874,6 +959,13 @@ __metadata: languageName: node linkType: hard +"@noble/ed25519@npm:^1.7.1": + version: 1.7.3 + resolution: "@noble/ed25519@npm:1.7.3" + checksum: 45169927d51de513e47bbeebff3a603433c4ac7579e1b8c5034c380a0afedbe85e6959be3d69584a7a5ed6828d638f8f28879003b9bb2fb5f22d8aa2d88fd5fe + languageName: node + linkType: hard + "@noble/hashes@npm:1.3.2, @noble/hashes@npm:^1.3.1": version: 1.3.2 resolution: "@noble/hashes@npm:1.3.2" @@ -881,6 +973,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.3.0, @noble/hashes@npm:^1.4.0": + version: 1.4.0 + resolution: "@noble/hashes@npm:1.4.0" + checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 + languageName: node + linkType: hard + "@noble/hashes@npm:1.7.0": version: 1.7.0 resolution: "@noble/hashes@npm:1.7.0" @@ -888,13 +987,6 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:^1.4.0": - version: 1.4.0 - resolution: "@noble/hashes@npm:1.4.0" - checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 - languageName: node - linkType: hard - "@npmcli/fs@npm:^3.1.0": version: 3.1.0 resolution: "@npmcli/fs@npm:3.1.0" @@ -918,6 +1010,125 @@ __metadata: languageName: node linkType: hard +"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/aspromise@npm:1.1.2" + checksum: 011fe7ef0826b0fd1a95935a033a3c0fd08483903e1aa8f8b4e0704e3233406abb9ee25350ec0c20bbecb2aad8da0dcea58b392bbd77d6690736f02c143865d2 + languageName: node + linkType: hard + +"@protobufjs/base64@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/base64@npm:1.1.2" + checksum: 67173ac34de1e242c55da52c2f5bdc65505d82453893f9b51dc74af9fe4c065cf4a657a4538e91b0d4a1a1e0a0642215e31894c31650ff6e3831471061e1ee9e + languageName: node + linkType: hard + +"@protobufjs/codegen@npm:^2.0.4": + version: 2.0.4 + resolution: "@protobufjs/codegen@npm:2.0.4" + checksum: 59240c850b1d3d0b56d8f8098dd04787dcaec5c5bd8de186fa548de86b86076e1c50e80144b90335e705a044edf5bc8b0998548474c2a10a98c7e004a1547e4b + languageName: node + linkType: hard + +"@protobufjs/eventemitter@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/eventemitter@npm:1.1.0" + checksum: 0369163a3d226851682f855f81413cbf166cd98f131edb94a0f67f79e75342d86e89df9d7a1df08ac28be2bc77e0a7f0200526bb6c2a407abbfee1f0262d5fd7 + languageName: node + linkType: hard + +"@protobufjs/fetch@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/fetch@npm:1.1.0" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.1" + "@protobufjs/inquire": "npm:^1.1.0" + checksum: 3fce7e09eb3f1171dd55a192066450f65324fd5f7cc01a431df01bb00d0a895e6bfb5b0c5561ce157ee1d886349c90703d10a4e11a1a256418ff591b969b3477 + languageName: node + linkType: hard + +"@protobufjs/float@npm:^1.0.2": + version: 1.0.2 + resolution: "@protobufjs/float@npm:1.0.2" + checksum: 5781e1241270b8bd1591d324ca9e3a3128d2f768077a446187a049e36505e91bc4156ed5ac3159c3ce3d2ba3743dbc757b051b2d723eea9cd367bfd54ab29b2f + languageName: node + linkType: hard + +"@protobufjs/inquire@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/inquire@npm:1.1.0" + checksum: ca06f02eaf65ca36fb7498fc3492b7fc087bfcc85c702bac5b86fad34b692bdce4990e0ef444c1e2aea8c034227bd1f0484be02810d5d7e931c55445555646f4 + languageName: node + linkType: hard + +"@protobufjs/path@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/path@npm:1.1.2" + checksum: 856eeb532b16a7aac071cacde5c5620df800db4c80cee6dbc56380524736205aae21e5ae47739114bf669ab5e8ba0e767a282ad894f3b5e124197cb9224445ee + languageName: node + linkType: hard + +"@protobufjs/pool@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/pool@npm:1.1.0" + checksum: d6a34fbbd24f729e2a10ee915b74e1d77d52214de626b921b2d77288bd8f2386808da2315080f2905761527cceffe7ec34c7647bd21a5ae41a25e8212ff79451 + languageName: node + linkType: hard + +"@protobufjs/utf8@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/utf8@npm:1.1.0" + checksum: f9bf3163d13aaa3b6f5e6fbf37a116e094ea021c0e1f2a7ccd0e12a29e2ce08dafba4e8b36e13f8ed7397e1591610ce880ed1289af4d66cf4ace8a36a9557278 + languageName: node + linkType: hard + +"@pythnetwork/hermes-client@npm:^2.0.0": + version: 2.0.0 + resolution: "@pythnetwork/hermes-client@npm:2.0.0" + dependencies: + "@zodios/core": ^10.9.6 + eventsource: ^3.0.5 + zod: ^3.23.8 + checksum: d5432c7c83617993a8e32fa4fde578e3b167ea348e5d3e2c681ee7bcf0e311824e00423d5529628f376f3541c888b9a12ed6c04135ea2e2f5872ab638a2dd31c + languageName: node + linkType: hard + +"@pythnetwork/price-service-sdk@npm:1.8.0": + version: 1.8.0 + resolution: "@pythnetwork/price-service-sdk@npm:1.8.0" + dependencies: + bn.js: ^5.2.1 + checksum: e843017db8469bc50c0e77b3db39c9756ff8d1c607a45626797ec4446121b9430770abcddcc15e08be132fa6081a5d872f0f79334cefceb7a1e7455300a1a426 + languageName: node + linkType: hard + +"@pythnetwork/pyth-solana-receiver@npm:^0.10.2": + version: 0.10.2 + resolution: "@pythnetwork/pyth-solana-receiver@npm:0.10.2" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@noble/hashes": ^1.4.0 + "@pythnetwork/price-service-sdk": 1.8.0 + "@pythnetwork/solana-utils": 0.4.5 + "@solana/web3.js": ^1.90.0 + checksum: 0b4376cb5c927d7571ca1b91216d47251a10aff52faf3d1581b8ac267facdb8214fedea7567e2266b2ba6f31cdb8ae44e6aa2ff7688f368c0582d4d59e89a287 + languageName: node + linkType: hard + +"@pythnetwork/solana-utils@npm:0.4.5": + version: 0.4.5 + resolution: "@pythnetwork/solana-utils@npm:0.4.5" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@solana/web3.js": ^1.90.0 + bs58: ^5.0.0 + jito-ts: ^3.0.1 + ts-log: ^2.2.7 + checksum: b877f2147a008403e13939b1b8e8a67d4d19432e46231b28c08d399010408093e9bad553ea2a7d7640496e37f1feac3e9fc01b8895f61c2d2617226a0d92d61e + languageName: node + linkType: hard + "@solana/buffer-layout-utils@npm:^0.2.0": version: 0.2.0 resolution: "@solana/buffer-layout-utils@npm:0.2.0" @@ -1054,6 +1265,52 @@ __metadata: languageName: node linkType: hard +"@solana/web3.js@npm:^1.90.0": + version: 1.93.0 + resolution: "@solana/web3.js@npm:1.93.0" + dependencies: + "@babel/runtime": ^7.24.7 + "@noble/curves": ^1.4.0 + "@noble/hashes": ^1.4.0 + "@solana/buffer-layout": ^4.0.1 + agentkeepalive: ^4.5.0 + bigint-buffer: ^1.1.5 + bn.js: ^5.2.1 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.0 + node-fetch: ^2.7.0 + rpc-websockets: ^9.0.0 + superstruct: ^1.0.4 + checksum: 3ae7d1e0cd998481b0d17076aec5df8c8593e7a9927ea245db19b18473abe3c96b94553de1f130ae1662a65a57b372a49025da38eeec598eb6c8ef355891b8b4 + languageName: node + linkType: hard + +"@solana/web3.js@npm:~1.77.3": + version: 1.77.4 + resolution: "@solana/web3.js@npm:1.77.4" + dependencies: + "@babel/runtime": ^7.12.5 + "@noble/curves": ^1.0.0 + "@noble/hashes": ^1.3.0 + "@solana/buffer-layout": ^4.0.0 + agentkeepalive: ^4.2.1 + bigint-buffer: ^1.1.5 + bn.js: ^5.0.0 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.0 + node-fetch: ^2.6.7 + rpc-websockets: ^7.5.1 + superstruct: ^0.14.2 + checksum: 7cd705244e83e74500ec3493b5d1743cc2c7d966c5775847baae356102602f65d35c5a2d9bca9a898bea0d05df057002b5c7660b9543ce7a8457442a20f24406 + languageName: node + linkType: hard + "@sqds/sdk@npm:2.0.4": version: 2.0.4 resolution: "@sqds/sdk@npm:2.0.4" @@ -1247,7 +1504,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*": +"@types/node@npm:*, @types/node@npm:>=13.7.0": version: 20.5.7 resolution: "@types/node@npm:20.5.7" checksum: fc284c8e16ddc04569730d58e87eae349eb1c3dd9020cb79a1862d9d9add6f04e7367a236f3252db8db2572f90278e250f4cd43d27d264972b54394eaba1ed76 @@ -1367,6 +1624,16 @@ __metadata: languageName: node linkType: hard +"@zodios/core@npm:^10.9.6": + version: 10.9.6 + resolution: "@zodios/core@npm:10.9.6" + peerDependencies: + axios: ^0.x || ^1.0.0 + zod: ^3.x + checksum: 482a80bd4da661734f9ed276a92d9275fa1b76011bef26ede4a851e4c495d9103e6c9456074b9e50e4c89ad7e83fcead6ea45ffba615e6ff54b8088433ba47fc + languageName: node + linkType: hard + "JSONStream@npm:^1.3.5": version: 1.3.5 resolution: "JSONStream@npm:1.3.5" @@ -2264,6 +2531,22 @@ __metadata: languageName: node linkType: hard +"eventsource-parser@npm:^3.0.1": + version: 3.0.3 + resolution: "eventsource-parser@npm:3.0.3" + checksum: a052aaedb89da8744219aea539343dabc54c6e032acc47f182a90fbbb083583208fbe0f786d7bc1182da098c88a391b7881b59a3fc921a73b718f25d1ee37425 + languageName: node + linkType: hard + +"eventsource@npm:^3.0.5": + version: 3.0.7 + resolution: "eventsource@npm:3.0.7" + dependencies: + eventsource-parser: ^3.0.1 + checksum: cd8cbc3418238b9d751b6652edf442d4b869829fbc3b73444abca1816fe3d23dc707130dd9a990360bc27c281d986f2f62059d870921173425c3ac28d20a8414 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -3007,7 +3290,7 @@ __metadata: languageName: node linkType: hard -"jayson@npm:^4.1.0": +"jayson@npm:^4.0.0, jayson@npm:^4.1.0": version: 4.1.0 resolution: "jayson@npm:4.1.0" dependencies: @@ -3051,6 +3334,22 @@ __metadata: languageName: node linkType: hard +"jito-ts@npm:^3.0.1": + version: 3.0.1 + resolution: "jito-ts@npm:3.0.1" + dependencies: + "@grpc/grpc-js": ^1.8.13 + "@noble/ed25519": ^1.7.1 + "@solana/web3.js": ~1.77.3 + agentkeepalive: ^4.3.0 + dotenv: ^16.0.3 + jayson: ^4.0.0 + node-fetch: ^2.6.7 + superstruct: ^1.0.3 + checksum: bdacbba32601be1e1b6a9a96c9cf9ba6c16fc265da5f936295146099c3e86205ef46d67e771545452c1213a48de5008fcd3ce41c786afce03586d583a00f9319 + languageName: node + linkType: hard + "jmespath@npm:0.16.0": version: 0.16.0 resolution: "jmespath@npm:0.16.0" @@ -3143,6 +3442,13 @@ __metadata: languageName: node linkType: hard +"lodash.camelcase@npm:^4.3.0": + version: 4.3.0 + resolution: "lodash.camelcase@npm:4.3.0" + checksum: cb9227612f71b83e42de93eccf1232feeb25e705bdb19ba26c04f91e885bfd3dd5c517c4a97137658190581d3493ea3973072ca010aab7e301046d90740393d1 + languageName: node + linkType: hard + "lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" @@ -3150,6 +3456,13 @@ __metadata: languageName: node linkType: hard +"long@npm:^5.0.0": + version: 5.2.3 + resolution: "long@npm:5.2.3" + checksum: 885ede7c3de4facccbd2cacc6168bae3a02c3e836159ea4252c87b6e34d40af819824b2d4edce330bfb5c4d6e8ce3ec5864bdcf9473fa1f53a4f8225860e5897 + languageName: node + linkType: hard + "lower-case@npm:^2.0.2": version: 2.0.2 resolution: "lower-case@npm:2.0.2" @@ -3430,7 +3743,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.12, node-fetch@npm:^2.7.0": +"node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.7, node-fetch@npm:^2.7.0": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -3871,6 +4184,26 @@ __metadata: languageName: node linkType: hard +"protobufjs@npm:^7.2.5": + version: 7.3.2 + resolution: "protobufjs@npm:7.3.2" + dependencies: + "@protobufjs/aspromise": ^1.1.2 + "@protobufjs/base64": ^1.1.2 + "@protobufjs/codegen": ^2.0.4 + "@protobufjs/eventemitter": ^1.1.0 + "@protobufjs/fetch": ^1.1.0 + "@protobufjs/float": ^1.0.2 + "@protobufjs/inquire": ^1.1.0 + "@protobufjs/path": ^1.1.2 + "@protobufjs/pool": ^1.1.0 + "@protobufjs/utf8": ^1.1.0 + "@types/node": ">=13.7.0" + long: ^5.0.0 + checksum: cfb2a744787f26ee7c82f3e7c4b72cfc000e9bb4c07828ed78eb414db0ea97a340c0cc3264d0e88606592f847b12c0351411f10e9af255b7ba864eec44d7705f + languageName: node + linkType: hard + "proxy-addr@npm:^2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" @@ -4046,6 +4379,28 @@ __metadata: languageName: node linkType: hard +"rpc-websockets@npm:^9.0.0": + version: 9.0.1 + resolution: "rpc-websockets@npm:9.0.1" + dependencies: + "@swc/helpers": ^0.5.11 + "@types/uuid": ^8.3.4 + "@types/ws": ^8.2.2 + buffer: ^6.0.3 + bufferutil: ^4.0.1 + eventemitter3: ^5.0.1 + utf-8-validate: ^5.0.2 + uuid: ^8.3.2 + ws: ^8.5.0 + dependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: f268741ca904b7ab0845188a8cadd61b6872228a76eb3cedcd96be9bd8b9a3fab9113b0ff9a9c2a85179fa337cb52b1d48bdaeb21ff46bc71cdaae20cf80dc3b + languageName: node + linkType: hard + "rpc-websockets@npm:^9.0.2": version: 9.0.4 resolution: "rpc-websockets@npm:9.0.4" @@ -4389,6 +4744,13 @@ __metadata: languageName: node linkType: hard +"superstruct@npm:^1.0.3, superstruct@npm:^1.0.4": + version: 1.0.4 + resolution: "superstruct@npm:1.0.4" + checksum: 2e070994cc4998a753c3f0215449d6de01ffb8180e4f46527f559ffbc2ebcc40fcf428f545ccd355921ef2920db7d138a96258ae35c788e6c24b2aa8bb1695cb + languageName: node + linkType: hard + "superstruct@npm:^2.0.2": version: 2.0.2 resolution: "superstruct@npm:2.0.2" @@ -4530,6 +4892,13 @@ __metadata: languageName: node linkType: hard +"ts-log@npm:^2.2.7": + version: 2.2.7 + resolution: "ts-log@npm:2.2.7" + checksum: c423a5eb54abb9471578902953814d3d0c88b3f237db016998f8998ecf982cb0f748bb8ebf93670eeba9b836ff0ce407d8065a340f3ab218ea7b9442c255b3d4 + languageName: node + linkType: hard + "ts-node@npm:^10.9.1": version: 10.9.1 resolution: "ts-node@npm:10.9.1" @@ -4900,7 +5269,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.7.1": +"yargs@npm:^17.7.1, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: @@ -4921,3 +5290,10 @@ __metadata: checksum: 2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6 languageName: node linkType: hard + +"zod@npm:^3.23.8": + version: 3.25.76 + resolution: "zod@npm:3.25.76" + checksum: c9a403a62b329188a5f6bd24d5d935d2bba345f7ab8151d1baa1505b5da9f227fb139354b043711490c798e91f3df75991395e40142e6510a4b16409f302b849 + languageName: node + linkType: hard diff --git a/packages/helium-vote-service/Dockerfile b/packages/helium-vote-service/Dockerfile index 090292cfd..5cab115dc 100644 --- a/packages/helium-vote-service/Dockerfile +++ b/packages/helium-vote-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/metadata-service/Dockerfile b/packages/metadata-service/Dockerfile index 2a9fe34c3..0fd7a7dde 100644 --- a/packages/metadata-service/Dockerfile +++ b/packages/metadata-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/metadata-service/yarn.deploy.lock b/packages/metadata-service/yarn.deploy.lock index 339755f35..a2cbb4966 100644 --- a/packages/metadata-service/yarn.deploy.lock +++ b/packages/metadata-service/yarn.deploy.lock @@ -5,6 +5,15 @@ __metadata: version: 6 cacheKey: 8 +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/runtime@npm:7.24.7" + dependencies: + regenerator-runtime: ^0.14.0 + checksum: d17f29eed6f848ac15cdf4202a910b741facfb0419a9d79e5c7fa37df6362fc3227f1cc2e248cc6db5e53ddffb4caa6686c488e6e80ce3d29c36a4e74c8734ea + languageName: node + linkType: hard + "@babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.22.6": version: 7.22.11 resolution: "@babel/runtime@npm:7.22.11" @@ -53,6 +62,28 @@ __metadata: languageName: node linkType: hard +"@coral-xyz/anchor@npm:^0.29.0": + version: 0.29.0 + resolution: "@coral-xyz/anchor@npm:0.29.0" + dependencies: + "@coral-xyz/borsh": ^0.29.0 + "@noble/hashes": ^1.3.1 + "@solana/web3.js": ^1.68.0 + bn.js: ^5.1.2 + bs58: ^4.0.1 + buffer-layout: ^1.2.2 + camelcase: ^6.3.0 + cross-fetch: ^3.1.5 + crypto-hash: ^1.3.0 + eventemitter3: ^4.0.7 + pako: ^2.0.3 + snake-case: ^3.0.4 + superstruct: ^0.15.4 + toml: ^3.0.0 + checksum: 10c4e6c5557653419683f5ae22ec47ac266b64e5b422d466885cf2dc7efa8f836239bdf321495d3e2b3ce03e766667c0e2192cc573fbd66bc12cc652f5146e10 + languageName: node + linkType: hard + "@coral-xyz/anchor@npm:^0.31.0": version: 0.31.0 resolution: "@coral-xyz/anchor@npm:0.31.0" @@ -86,6 +117,18 @@ __metadata: languageName: node linkType: hard +"@coral-xyz/borsh@npm:^0.29.0": + version: 0.29.0 + resolution: "@coral-xyz/borsh@npm:0.29.0" + dependencies: + bn.js: ^5.1.2 + buffer-layout: ^1.2.0 + peerDependencies: + "@solana/web3.js": ^1.68.0 + checksum: 37006c75cd012672adf48e10234062624634da2a9335e34b7ff30969f58aff78cc3073b66a3edc806b52f038469f0c477a5a3ed35aaa075f3cbd44d7133ac218 + languageName: node + linkType: hard + "@coral-xyz/borsh@npm:^0.31.0": version: 0.31.0 resolution: "@coral-xyz/borsh@npm:0.31.0" @@ -214,6 +257,30 @@ __metadata: languageName: node linkType: hard +"@grpc/grpc-js@npm:^1.8.13": + version: 1.10.9 + resolution: "@grpc/grpc-js@npm:1.10.9" + dependencies: + "@grpc/proto-loader": ^0.7.13 + "@js-sdsl/ordered-map": ^4.4.2 + checksum: 88d91c227175275d8cc178c807d09510a83d947911c9bfe8ccd132cb27144c54508bcd114d52ab00b6e4f37eecf74aeee3ef3971900bdb90735d55a0b0dba761 + languageName: node + linkType: hard + +"@grpc/proto-loader@npm:^0.7.13": + version: 0.7.13 + resolution: "@grpc/proto-loader@npm:0.7.13" + dependencies: + lodash.camelcase: ^4.3.0 + long: ^5.0.0 + protobufjs: ^7.2.5 + yargs: ^17.7.2 + bin: + proto-loader-gen-types: build/bin/proto-loader-gen-types.js + checksum: 399c1b8a4627f93dc31660d9636ea6bf58be5675cc7581e3df56a249369e5be02c6cd0d642c5332b0d5673bc8621619bc06fb045aa3e8f57383737b5d35930dc + languageName: node + linkType: hard + "@grpc/proto-loader@npm:^0.7.8": version: 0.7.10 resolution: "@grpc/proto-loader@npm:0.7.10" @@ -291,6 +358,8 @@ __metadata: "@helium/helium-sub-daos-sdk": ^0.10.35 "@helium/idls": ^0.10.35 "@helium/spl-utils": ^0.10.35 + "@pythnetwork/hermes-client": ^2.0.0 + "@pythnetwork/pyth-solana-receiver": ^0.10.2 bn.js: ^5.2.0 bs58: ^4.0.1 git-format-staged: ^2.1.3 @@ -533,6 +602,13 @@ __metadata: languageName: node linkType: hard +"@js-sdsl/ordered-map@npm:^4.4.2": + version: 4.4.2 + resolution: "@js-sdsl/ordered-map@npm:4.4.2" + checksum: a927ae4ff8565ecb75355cc6886a4f8fadbf2af1268143c96c0cce3ba01261d241c3f4ba77f21f3f017a00f91dfe9e0673e95f830255945c80a0e96c6d30508a + languageName: node + linkType: hard + "@lukeed/ms@npm:^2.0.2": version: 2.0.2 resolution: "@lukeed/ms@npm:2.0.2" @@ -613,6 +689,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:^1.4.0": + version: 1.4.0 + resolution: "@noble/curves@npm:1.4.0" + dependencies: + "@noble/hashes": 1.4.0 + checksum: 0014ff561d16e98da4a57e2310a4015e4bdab3b1e1eafcd18d3f9b955c29c3501452ca5d702fddf8ca92d570bbeadfbe53fe16ebbd81a319c414f739154bb26b + languageName: node + linkType: hard + "@noble/curves@npm:^1.4.2": version: 1.8.0 resolution: "@noble/curves@npm:1.8.0" @@ -622,6 +707,13 @@ __metadata: languageName: node linkType: hard +"@noble/ed25519@npm:^1.7.1": + version: 1.7.3 + resolution: "@noble/ed25519@npm:1.7.3" + checksum: 45169927d51de513e47bbeebff3a603433c4ac7579e1b8c5034c380a0afedbe85e6959be3d69584a7a5ed6828d638f8f28879003b9bb2fb5f22d8aa2d88fd5fe + languageName: node + linkType: hard + "@noble/hashes@npm:1.3.2, @noble/hashes@npm:^1.3.1": version: 1.3.2 resolution: "@noble/hashes@npm:1.3.2" @@ -629,6 +721,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.3.0, @noble/hashes@npm:^1.4.0": + version: 1.4.0 + resolution: "@noble/hashes@npm:1.4.0" + checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 + languageName: node + linkType: hard + "@noble/hashes@npm:1.7.0": version: 1.7.0 resolution: "@noble/hashes@npm:1.7.0" @@ -636,13 +735,6 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:^1.4.0": - version: 1.4.0 - resolution: "@noble/hashes@npm:1.4.0" - checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 - languageName: node - linkType: hard - "@npmcli/fs@npm:^3.1.0": version: 3.1.0 resolution: "@npmcli/fs@npm:3.1.0" @@ -732,6 +824,52 @@ __metadata: languageName: node linkType: hard +"@pythnetwork/hermes-client@npm:^2.0.0": + version: 2.0.0 + resolution: "@pythnetwork/hermes-client@npm:2.0.0" + dependencies: + "@zodios/core": ^10.9.6 + eventsource: ^3.0.5 + zod: ^3.23.8 + checksum: d5432c7c83617993a8e32fa4fde578e3b167ea348e5d3e2c681ee7bcf0e311824e00423d5529628f376f3541c888b9a12ed6c04135ea2e2f5872ab638a2dd31c + languageName: node + linkType: hard + +"@pythnetwork/price-service-sdk@npm:1.8.0": + version: 1.8.0 + resolution: "@pythnetwork/price-service-sdk@npm:1.8.0" + dependencies: + bn.js: ^5.2.1 + checksum: e843017db8469bc50c0e77b3db39c9756ff8d1c607a45626797ec4446121b9430770abcddcc15e08be132fa6081a5d872f0f79334cefceb7a1e7455300a1a426 + languageName: node + linkType: hard + +"@pythnetwork/pyth-solana-receiver@npm:^0.10.2": + version: 0.10.2 + resolution: "@pythnetwork/pyth-solana-receiver@npm:0.10.2" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@noble/hashes": ^1.4.0 + "@pythnetwork/price-service-sdk": 1.8.0 + "@pythnetwork/solana-utils": 0.4.5 + "@solana/web3.js": ^1.90.0 + checksum: 0b4376cb5c927d7571ca1b91216d47251a10aff52faf3d1581b8ac267facdb8214fedea7567e2266b2ba6f31cdb8ae44e6aa2ff7688f368c0582d4d59e89a287 + languageName: node + linkType: hard + +"@pythnetwork/solana-utils@npm:0.4.5": + version: 0.4.5 + resolution: "@pythnetwork/solana-utils@npm:0.4.5" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@solana/web3.js": ^1.90.0 + bs58: ^5.0.0 + jito-ts: ^3.0.1 + ts-log: ^2.2.7 + checksum: b877f2147a008403e13939b1b8e8a67d4d19432e46231b28c08d399010408093e9bad553ea2a7d7640496e37f1feac3e9fc01b8895f61c2d2617226a0d92d61e + languageName: node + linkType: hard + "@solana/buffer-layout-utils@npm:^0.2.0": version: 0.2.0 resolution: "@solana/buffer-layout-utils@npm:0.2.0" @@ -828,6 +966,52 @@ __metadata: languageName: node linkType: hard +"@solana/web3.js@npm:^1.90.0": + version: 1.93.0 + resolution: "@solana/web3.js@npm:1.93.0" + dependencies: + "@babel/runtime": ^7.24.7 + "@noble/curves": ^1.4.0 + "@noble/hashes": ^1.4.0 + "@solana/buffer-layout": ^4.0.1 + agentkeepalive: ^4.5.0 + bigint-buffer: ^1.1.5 + bn.js: ^5.2.1 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.0 + node-fetch: ^2.7.0 + rpc-websockets: ^9.0.0 + superstruct: ^1.0.4 + checksum: 3ae7d1e0cd998481b0d17076aec5df8c8593e7a9927ea245db19b18473abe3c96b94553de1f130ae1662a65a57b372a49025da38eeec598eb6c8ef355891b8b4 + languageName: node + linkType: hard + +"@solana/web3.js@npm:~1.77.3": + version: 1.77.4 + resolution: "@solana/web3.js@npm:1.77.4" + dependencies: + "@babel/runtime": ^7.12.5 + "@noble/curves": ^1.0.0 + "@noble/hashes": ^1.3.0 + "@solana/buffer-layout": ^4.0.0 + agentkeepalive: ^4.2.1 + bigint-buffer: ^1.1.5 + bn.js: ^5.0.0 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.0 + node-fetch: ^2.6.7 + rpc-websockets: ^7.5.1 + superstruct: ^0.14.2 + checksum: 7cd705244e83e74500ec3493b5d1743cc2c7d966c5775847baae356102602f65d35c5a2d9bca9a898bea0d05df057002b5c7660b9543ce7a8457442a20f24406 + languageName: node + linkType: hard + "@swc/helpers@npm:^0.5.11": version: 0.5.11 resolution: "@swc/helpers@npm:0.5.11" @@ -985,6 +1169,16 @@ __metadata: languageName: node linkType: hard +"@zodios/core@npm:^10.9.6": + version: 10.9.6 + resolution: "@zodios/core@npm:10.9.6" + peerDependencies: + axios: ^0.x || ^1.0.0 + zod: ^3.x + checksum: 482a80bd4da661734f9ed276a92d9275fa1b76011bef26ede4a851e4c495d9103e6c9456074b9e50e4c89ad7e83fcead6ea45ffba615e6ff54b8088433ba47fc + languageName: node + linkType: hard + "JSONStream@npm:^1.3.5": version: 1.3.5 resolution: "JSONStream@npm:1.3.5" @@ -1306,7 +1500,7 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": +"bn.js@npm:^5.0.0, bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": version: 5.2.1 resolution: "bn.js@npm:5.2.1" checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 @@ -1713,7 +1907,7 @@ __metadata: languageName: node linkType: hard -"dotenv@npm:^16.3.1": +"dotenv@npm:^16.0.3, dotenv@npm:^16.3.1": version: 16.3.1 resolution: "dotenv@npm:16.3.1" checksum: 15d75e7279018f4bafd0ee9706593dd14455ddb71b3bcba9c52574460b7ccaf67d5cf8b2c08a5af1a9da6db36c956a04a1192b101ee102a3e0cf8817bbcf3dfd @@ -1887,6 +2081,22 @@ __metadata: languageName: node linkType: hard +"eventsource-parser@npm:^3.0.1": + version: 3.0.3 + resolution: "eventsource-parser@npm:3.0.3" + checksum: a052aaedb89da8744219aea539343dabc54c6e032acc47f182a90fbbb083583208fbe0f786d7bc1182da098c88a391b7881b59a3fc921a73b718f25d1ee37425 + languageName: node + linkType: hard + +"eventsource@npm:^3.0.5": + version: 3.0.7 + resolution: "eventsource@npm:3.0.7" + dependencies: + eventsource-parser: ^3.0.1 + checksum: cd8cbc3418238b9d751b6652edf442d4b869829fbc3b73444abca1816fe3d23dc707130dd9a990360bc27c281d986f2f62059d870921173425c3ac28d20a8414 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -2655,7 +2865,7 @@ __metadata: languageName: node linkType: hard -"jayson@npm:^4.1.0": +"jayson@npm:^4.0.0, jayson@npm:^4.1.0": version: 4.1.0 resolution: "jayson@npm:4.1.0" dependencies: @@ -2699,6 +2909,22 @@ __metadata: languageName: node linkType: hard +"jito-ts@npm:^3.0.1": + version: 3.0.1 + resolution: "jito-ts@npm:3.0.1" + dependencies: + "@grpc/grpc-js": ^1.8.13 + "@noble/ed25519": ^1.7.1 + "@solana/web3.js": ~1.77.3 + agentkeepalive: ^4.3.0 + dotenv: ^16.0.3 + jayson: ^4.0.0 + node-fetch: ^2.6.7 + superstruct: ^1.0.3 + checksum: bdacbba32601be1e1b6a9a96c9cf9ba6c16fc265da5f936295146099c3e86205ef46d67e771545452c1213a48de5008fcd3ce41c786afce03586d583a00f9319 + languageName: node + linkType: hard + "jmespath@npm:0.16.0": version: 0.16.0 resolution: "jmespath@npm:0.16.0" @@ -3495,6 +3721,26 @@ __metadata: languageName: node linkType: hard +"protobufjs@npm:^7.2.5": + version: 7.3.2 + resolution: "protobufjs@npm:7.3.2" + dependencies: + "@protobufjs/aspromise": ^1.1.2 + "@protobufjs/base64": ^1.1.2 + "@protobufjs/codegen": ^2.0.4 + "@protobufjs/eventemitter": ^1.1.0 + "@protobufjs/fetch": ^1.1.0 + "@protobufjs/float": ^1.0.2 + "@protobufjs/inquire": ^1.1.0 + "@protobufjs/path": ^1.1.2 + "@protobufjs/pool": ^1.1.0 + "@protobufjs/utf8": ^1.1.0 + "@types/node": ">=13.7.0" + long: ^5.0.0 + checksum: cfb2a744787f26ee7c82f3e7c4b72cfc000e9bb4c07828ed78eb414db0ea97a340c0cc3264d0e88606592f847b12c0351411f10e9af255b7ba864eec44d7705f + languageName: node + linkType: hard + "proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" @@ -3687,6 +3933,28 @@ __metadata: languageName: node linkType: hard +"rpc-websockets@npm:^9.0.0": + version: 9.0.1 + resolution: "rpc-websockets@npm:9.0.1" + dependencies: + "@swc/helpers": ^0.5.11 + "@types/uuid": ^8.3.4 + "@types/ws": ^8.2.2 + buffer: ^6.0.3 + bufferutil: ^4.0.1 + eventemitter3: ^5.0.1 + utf-8-validate: ^5.0.2 + uuid: ^8.3.2 + ws: ^8.5.0 + dependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: f268741ca904b7ab0845188a8cadd61b6872228a76eb3cedcd96be9bd8b9a3fab9113b0ff9a9c2a85179fa337cb52b1d48bdaeb21ff46bc71cdaae20cf80dc3b + languageName: node + linkType: hard + "rpc-websockets@npm:^9.0.2": version: 9.0.4 resolution: "rpc-websockets@npm:9.0.4" @@ -4054,6 +4322,13 @@ __metadata: languageName: node linkType: hard +"superstruct@npm:^1.0.3, superstruct@npm:^1.0.4": + version: 1.0.4 + resolution: "superstruct@npm:1.0.4" + checksum: 2e070994cc4998a753c3f0215449d6de01ffb8180e4f46527f559ffbc2ebcc40fcf428f545ccd355921ef2920db7d138a96258ae35c788e6c24b2aa8bb1695cb + languageName: node + linkType: hard + "superstruct@npm:^2.0.2": version: 2.0.2 resolution: "superstruct@npm:2.0.2" @@ -4189,6 +4464,13 @@ __metadata: languageName: node linkType: hard +"ts-log@npm:^2.2.7": + version: 2.2.7 + resolution: "ts-log@npm:2.2.7" + checksum: c423a5eb54abb9471578902953814d3d0c88b3f237db016998f8998ecf982cb0f748bb8ebf93670eeba9b836ff0ce407d8065a340f3ab218ea7b9442c255b3d4 + languageName: node + linkType: hard + "ts-node-dev@npm:^2.0.0": version: 2.0.0 resolution: "ts-node-dev@npm:2.0.0" @@ -4616,3 +4898,10 @@ __metadata: checksum: 2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6 languageName: node linkType: hard + +"zod@npm:^3.23.8": + version: 3.25.76 + resolution: "zod@npm:3.25.76" + checksum: c9a403a62b329188a5f6bd24d5d935d2bba345f7ab8151d1baa1505b5da9f227fb139354b043711490c798e91f3df75991395e40142e6510a4b16409f302b849 + languageName: node + linkType: hard diff --git a/packages/migration-service/Dockerfile b/packages/migration-service/Dockerfile index 26272f0a9..ab3c5193d 100644 --- a/packages/migration-service/Dockerfile +++ b/packages/migration-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -12,7 +12,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build RUN npm prune --production -FROM node:20-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/migration-service/yarn.deploy.lock b/packages/migration-service/yarn.deploy.lock index eaae6014d..bd3f2118a 100644 --- a/packages/migration-service/yarn.deploy.lock +++ b/packages/migration-service/yarn.deploy.lock @@ -14,6 +14,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/runtime@npm:7.24.7" + dependencies: + regenerator-runtime: ^0.14.0 + checksum: d17f29eed6f848ac15cdf4202a910b741facfb0419a9d79e5c7fa37df6362fc3227f1cc2e248cc6db5e53ddffb4caa6686c488e6e80ce3d29c36a4e74c8734ea + languageName: node + linkType: hard + "@babel/runtime@npm:^7.25.0": version: 7.26.0 resolution: "@babel/runtime@npm:7.26.0" @@ -86,6 +95,28 @@ __metadata: languageName: node linkType: hard +"@coral-xyz/anchor@npm:^0.29.0": + version: 0.29.0 + resolution: "@coral-xyz/anchor@npm:0.29.0" + dependencies: + "@coral-xyz/borsh": ^0.29.0 + "@noble/hashes": ^1.3.1 + "@solana/web3.js": ^1.68.0 + bn.js: ^5.1.2 + bs58: ^4.0.1 + buffer-layout: ^1.2.2 + camelcase: ^6.3.0 + cross-fetch: ^3.1.5 + crypto-hash: ^1.3.0 + eventemitter3: ^4.0.7 + pako: ^2.0.3 + snake-case: ^3.0.4 + superstruct: ^0.15.4 + toml: ^3.0.0 + checksum: 10c4e6c5557653419683f5ae22ec47ac266b64e5b422d466885cf2dc7efa8f836239bdf321495d3e2b3ce03e766667c0e2192cc573fbd66bc12cc652f5146e10 + languageName: node + linkType: hard + "@coral-xyz/anchor@npm:^0.31.0": version: 0.31.0 resolution: "@coral-xyz/anchor@npm:0.31.0" @@ -131,6 +162,18 @@ __metadata: languageName: node linkType: hard +"@coral-xyz/borsh@npm:^0.29.0": + version: 0.29.0 + resolution: "@coral-xyz/borsh@npm:0.29.0" + dependencies: + bn.js: ^5.1.2 + buffer-layout: ^1.2.0 + peerDependencies: + "@solana/web3.js": ^1.68.0 + checksum: 37006c75cd012672adf48e10234062624634da2a9335e34b7ff30969f58aff78cc3073b66a3edc806b52f038469f0c477a5a3ed35aaa075f3cbd44d7133ac218 + languageName: node + linkType: hard + "@coral-xyz/borsh@npm:^0.31.0": version: 0.31.0 resolution: "@coral-xyz/borsh@npm:0.31.0" @@ -205,6 +248,30 @@ __metadata: languageName: node linkType: hard +"@grpc/grpc-js@npm:^1.8.13": + version: 1.10.9 + resolution: "@grpc/grpc-js@npm:1.10.9" + dependencies: + "@grpc/proto-loader": ^0.7.13 + "@js-sdsl/ordered-map": ^4.4.2 + checksum: 88d91c227175275d8cc178c807d09510a83d947911c9bfe8ccd132cb27144c54508bcd114d52ab00b6e4f37eecf74aeee3ef3971900bdb90735d55a0b0dba761 + languageName: node + linkType: hard + +"@grpc/proto-loader@npm:^0.7.13": + version: 0.7.13 + resolution: "@grpc/proto-loader@npm:0.7.13" + dependencies: + lodash.camelcase: ^4.3.0 + long: ^5.0.0 + protobufjs: ^7.2.5 + yargs: ^17.7.2 + bin: + proto-loader-gen-types: build/bin/proto-loader-gen-types.js + checksum: 399c1b8a4627f93dc31660d9636ea6bf58be5675cc7581e3df56a249369e5be02c6cd0d642c5332b0d5673bc8621619bc06fb045aa3e8f57383737b5d35930dc + languageName: node + linkType: hard + "@helium/account-fetch-cache@^0.10.35": version: 0.0.0-use.local resolution: "@helium/account-fetch-cache@workspace:packages/account-fetch-cache" @@ -303,6 +370,8 @@ __metadata: "@helium/helium-sub-daos-sdk": ^0.10.35 "@helium/idls": ^0.10.35 "@helium/spl-utils": ^0.10.35 + "@pythnetwork/hermes-client": ^2.0.0 + "@pythnetwork/pyth-solana-receiver": ^0.10.2 bn.js: ^5.2.0 bs58: ^4.0.1 git-format-staged: ^2.1.3 @@ -739,6 +808,13 @@ __metadata: languageName: node linkType: hard +"@js-sdsl/ordered-map@npm:^4.4.2": + version: 4.4.2 + resolution: "@js-sdsl/ordered-map@npm:4.4.2" + checksum: a927ae4ff8565ecb75355cc6886a4f8fadbf2af1268143c96c0cce3ba01261d241c3f4ba77f21f3f017a00f91dfe9e0673e95f830255945c80a0e96c6d30508a + languageName: node + linkType: hard + "@metaplex-foundation/beet-solana@npm:0.4.0, @metaplex-foundation/beet-solana@npm:^0.4.0": version: 0.4.0 resolution: "@metaplex-foundation/beet-solana@npm:0.4.0" @@ -809,6 +885,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:^1.4.0": + version: 1.4.0 + resolution: "@noble/curves@npm:1.4.0" + dependencies: + "@noble/hashes": 1.4.0 + checksum: 0014ff561d16e98da4a57e2310a4015e4bdab3b1e1eafcd18d3f9b955c29c3501452ca5d702fddf8ca92d570bbeadfbe53fe16ebbd81a319c414f739154bb26b + languageName: node + linkType: hard + "@noble/curves@npm:^1.4.2": version: 1.8.0 resolution: "@noble/curves@npm:1.8.0" @@ -818,6 +903,13 @@ __metadata: languageName: node linkType: hard +"@noble/ed25519@npm:^1.7.1": + version: 1.7.3 + resolution: "@noble/ed25519@npm:1.7.3" + checksum: 45169927d51de513e47bbeebff3a603433c4ac7579e1b8c5034c380a0afedbe85e6959be3d69584a7a5ed6828d638f8f28879003b9bb2fb5f22d8aa2d88fd5fe + languageName: node + linkType: hard + "@noble/hashes@npm:1.3.2, @noble/hashes@npm:^1.3.1": version: 1.3.2 resolution: "@noble/hashes@npm:1.3.2" @@ -825,6 +917,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.3.0, @noble/hashes@npm:^1.4.0": + version: 1.4.0 + resolution: "@noble/hashes@npm:1.4.0" + checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 + languageName: node + linkType: hard + "@noble/hashes@npm:1.7.0": version: 1.7.0 resolution: "@noble/hashes@npm:1.7.0" @@ -832,13 +931,6 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:^1.4.0": - version: 1.4.0 - resolution: "@noble/hashes@npm:1.4.0" - checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 - languageName: node - linkType: hard - "@npmcli/fs@npm:^3.1.0": version: 3.1.0 resolution: "@npmcli/fs@npm:3.1.0" @@ -874,6 +966,125 @@ __metadata: languageName: node linkType: hard +"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/aspromise@npm:1.1.2" + checksum: 011fe7ef0826b0fd1a95935a033a3c0fd08483903e1aa8f8b4e0704e3233406abb9ee25350ec0c20bbecb2aad8da0dcea58b392bbd77d6690736f02c143865d2 + languageName: node + linkType: hard + +"@protobufjs/base64@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/base64@npm:1.1.2" + checksum: 67173ac34de1e242c55da52c2f5bdc65505d82453893f9b51dc74af9fe4c065cf4a657a4538e91b0d4a1a1e0a0642215e31894c31650ff6e3831471061e1ee9e + languageName: node + linkType: hard + +"@protobufjs/codegen@npm:^2.0.4": + version: 2.0.4 + resolution: "@protobufjs/codegen@npm:2.0.4" + checksum: 59240c850b1d3d0b56d8f8098dd04787dcaec5c5bd8de186fa548de86b86076e1c50e80144b90335e705a044edf5bc8b0998548474c2a10a98c7e004a1547e4b + languageName: node + linkType: hard + +"@protobufjs/eventemitter@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/eventemitter@npm:1.1.0" + checksum: 0369163a3d226851682f855f81413cbf166cd98f131edb94a0f67f79e75342d86e89df9d7a1df08ac28be2bc77e0a7f0200526bb6c2a407abbfee1f0262d5fd7 + languageName: node + linkType: hard + +"@protobufjs/fetch@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/fetch@npm:1.1.0" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.1" + "@protobufjs/inquire": "npm:^1.1.0" + checksum: 3fce7e09eb3f1171dd55a192066450f65324fd5f7cc01a431df01bb00d0a895e6bfb5b0c5561ce157ee1d886349c90703d10a4e11a1a256418ff591b969b3477 + languageName: node + linkType: hard + +"@protobufjs/float@npm:^1.0.2": + version: 1.0.2 + resolution: "@protobufjs/float@npm:1.0.2" + checksum: 5781e1241270b8bd1591d324ca9e3a3128d2f768077a446187a049e36505e91bc4156ed5ac3159c3ce3d2ba3743dbc757b051b2d723eea9cd367bfd54ab29b2f + languageName: node + linkType: hard + +"@protobufjs/inquire@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/inquire@npm:1.1.0" + checksum: ca06f02eaf65ca36fb7498fc3492b7fc087bfcc85c702bac5b86fad34b692bdce4990e0ef444c1e2aea8c034227bd1f0484be02810d5d7e931c55445555646f4 + languageName: node + linkType: hard + +"@protobufjs/path@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/path@npm:1.1.2" + checksum: 856eeb532b16a7aac071cacde5c5620df800db4c80cee6dbc56380524736205aae21e5ae47739114bf669ab5e8ba0e767a282ad894f3b5e124197cb9224445ee + languageName: node + linkType: hard + +"@protobufjs/pool@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/pool@npm:1.1.0" + checksum: d6a34fbbd24f729e2a10ee915b74e1d77d52214de626b921b2d77288bd8f2386808da2315080f2905761527cceffe7ec34c7647bd21a5ae41a25e8212ff79451 + languageName: node + linkType: hard + +"@protobufjs/utf8@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/utf8@npm:1.1.0" + checksum: f9bf3163d13aaa3b6f5e6fbf37a116e094ea021c0e1f2a7ccd0e12a29e2ce08dafba4e8b36e13f8ed7397e1591610ce880ed1289af4d66cf4ace8a36a9557278 + languageName: node + linkType: hard + +"@pythnetwork/hermes-client@npm:^2.0.0": + version: 2.0.0 + resolution: "@pythnetwork/hermes-client@npm:2.0.0" + dependencies: + "@zodios/core": ^10.9.6 + eventsource: ^3.0.5 + zod: ^3.23.8 + checksum: d5432c7c83617993a8e32fa4fde578e3b167ea348e5d3e2c681ee7bcf0e311824e00423d5529628f376f3541c888b9a12ed6c04135ea2e2f5872ab638a2dd31c + languageName: node + linkType: hard + +"@pythnetwork/price-service-sdk@npm:1.8.0": + version: 1.8.0 + resolution: "@pythnetwork/price-service-sdk@npm:1.8.0" + dependencies: + bn.js: ^5.2.1 + checksum: e843017db8469bc50c0e77b3db39c9756ff8d1c607a45626797ec4446121b9430770abcddcc15e08be132fa6081a5d872f0f79334cefceb7a1e7455300a1a426 + languageName: node + linkType: hard + +"@pythnetwork/pyth-solana-receiver@npm:^0.10.2": + version: 0.10.2 + resolution: "@pythnetwork/pyth-solana-receiver@npm:0.10.2" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@noble/hashes": ^1.4.0 + "@pythnetwork/price-service-sdk": 1.8.0 + "@pythnetwork/solana-utils": 0.4.5 + "@solana/web3.js": ^1.90.0 + checksum: 0b4376cb5c927d7571ca1b91216d47251a10aff52faf3d1581b8ac267facdb8214fedea7567e2266b2ba6f31cdb8ae44e6aa2ff7688f368c0582d4d59e89a287 + languageName: node + linkType: hard + +"@pythnetwork/solana-utils@npm:0.4.5": + version: 0.4.5 + resolution: "@pythnetwork/solana-utils@npm:0.4.5" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@solana/web3.js": ^1.90.0 + bs58: ^5.0.0 + jito-ts: ^3.0.1 + ts-log: ^2.2.7 + checksum: b877f2147a008403e13939b1b8e8a67d4d19432e46231b28c08d399010408093e9bad553ea2a7d7640496e37f1feac3e9fc01b8895f61c2d2617226a0d92d61e + languageName: node + linkType: hard + "@solana/buffer-layout-utils@npm:^0.2.0": version: 0.2.0 resolution: "@solana/buffer-layout-utils@npm:0.2.0" @@ -995,6 +1206,52 @@ __metadata: languageName: node linkType: hard +"@solana/web3.js@npm:^1.90.0": + version: 1.93.0 + resolution: "@solana/web3.js@npm:1.93.0" + dependencies: + "@babel/runtime": ^7.24.7 + "@noble/curves": ^1.4.0 + "@noble/hashes": ^1.4.0 + "@solana/buffer-layout": ^4.0.1 + agentkeepalive: ^4.5.0 + bigint-buffer: ^1.1.5 + bn.js: ^5.2.1 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.0 + node-fetch: ^2.7.0 + rpc-websockets: ^9.0.0 + superstruct: ^1.0.4 + checksum: 3ae7d1e0cd998481b0d17076aec5df8c8593e7a9927ea245db19b18473abe3c96b94553de1f130ae1662a65a57b372a49025da38eeec598eb6c8ef355891b8b4 + languageName: node + linkType: hard + +"@solana/web3.js@npm:~1.77.3": + version: 1.77.4 + resolution: "@solana/web3.js@npm:1.77.4" + dependencies: + "@babel/runtime": ^7.12.5 + "@noble/curves": ^1.0.0 + "@noble/hashes": ^1.3.0 + "@solana/buffer-layout": ^4.0.0 + agentkeepalive: ^4.2.1 + bigint-buffer: ^1.1.5 + bn.js: ^5.0.0 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.0 + node-fetch: ^2.6.7 + rpc-websockets: ^7.5.1 + superstruct: ^0.14.2 + checksum: 7cd705244e83e74500ec3493b5d1743cc2c7d966c5775847baae356102602f65d35c5a2d9bca9a898bea0d05df057002b5c7660b9543ce7a8457442a20f24406 + languageName: node + linkType: hard + "@swc/helpers@npm:^0.5.11": version: 0.5.11 resolution: "@swc/helpers@npm:0.5.11" @@ -1188,7 +1445,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*": +"@types/node@npm:*, @types/node@npm:>=13.7.0": version: 20.5.7 resolution: "@types/node@npm:20.5.7" checksum: fc284c8e16ddc04569730d58e87eae349eb1c3dd9020cb79a1862d9d9add6f04e7367a236f3252db8db2572f90278e250f4cd43d27d264972b54394eaba1ed76 @@ -1329,6 +1586,16 @@ __metadata: languageName: node linkType: hard +"@zodios/core@npm:^10.9.6": + version: 10.9.6 + resolution: "@zodios/core@npm:10.9.6" + peerDependencies: + axios: ^0.x || ^1.0.0 + zod: ^3.x + checksum: 482a80bd4da661734f9ed276a92d9275fa1b76011bef26ede4a851e4c495d9103e6c9456074b9e50e4c89ad7e83fcead6ea45ffba615e6ff54b8088433ba47fc + languageName: node + linkType: hard + "JSONStream@npm:^1.3.5": version: 1.3.5 resolution: "JSONStream@npm:1.3.5" @@ -1640,7 +1907,7 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^5.1.0, bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": +"bn.js@npm:^5.0.0, bn.js@npm:^5.1.0, bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": version: 5.2.1 resolution: "bn.js@npm:5.2.1" checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 @@ -2228,6 +2495,22 @@ __metadata: languageName: node linkType: hard +"eventsource-parser@npm:^3.0.1": + version: 3.0.3 + resolution: "eventsource-parser@npm:3.0.3" + checksum: a052aaedb89da8744219aea539343dabc54c6e032acc47f182a90fbbb083583208fbe0f786d7bc1182da098c88a391b7881b59a3fc921a73b718f25d1ee37425 + languageName: node + linkType: hard + +"eventsource@npm:^3.0.5": + version: 3.0.7 + resolution: "eventsource@npm:3.0.7" + dependencies: + eventsource-parser: ^3.0.1 + checksum: cd8cbc3418238b9d751b6652edf442d4b869829fbc3b73444abca1816fe3d23dc707130dd9a990360bc27c281d986f2f62059d870921173425c3ac28d20a8414 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -2963,7 +3246,7 @@ __metadata: languageName: node linkType: hard -"jayson@npm:^4.1.0": +"jayson@npm:^4.0.0, jayson@npm:^4.1.0": version: 4.1.0 resolution: "jayson@npm:4.1.0" dependencies: @@ -3007,6 +3290,22 @@ __metadata: languageName: node linkType: hard +"jito-ts@npm:^3.0.1": + version: 3.0.1 + resolution: "jito-ts@npm:3.0.1" + dependencies: + "@grpc/grpc-js": ^1.8.13 + "@noble/ed25519": ^1.7.1 + "@solana/web3.js": ~1.77.3 + agentkeepalive: ^4.3.0 + dotenv: ^16.0.3 + jayson: ^4.0.0 + node-fetch: ^2.6.7 + superstruct: ^1.0.3 + checksum: bdacbba32601be1e1b6a9a96c9cf9ba6c16fc265da5f936295146099c3e86205ef46d67e771545452c1213a48de5008fcd3ce41c786afce03586d583a00f9319 + languageName: node + linkType: hard + "jmespath@npm:0.16.0": version: 0.16.0 resolution: "jmespath@npm:0.16.0" @@ -3099,6 +3398,13 @@ __metadata: languageName: node linkType: hard +"lodash.camelcase@npm:^4.3.0": + version: 4.3.0 + resolution: "lodash.camelcase@npm:4.3.0" + checksum: cb9227612f71b83e42de93eccf1232feeb25e705bdb19ba26c04f91e885bfd3dd5c517c4a97137658190581d3493ea3973072ca010aab7e301046d90740393d1 + languageName: node + linkType: hard + "lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" @@ -3106,6 +3412,13 @@ __metadata: languageName: node linkType: hard +"long@npm:^5.0.0": + version: 5.2.3 + resolution: "long@npm:5.2.3" + checksum: 885ede7c3de4facccbd2cacc6168bae3a02c3e836159ea4252c87b6e34d40af819824b2d4edce330bfb5c4d6e8ce3ec5864bdcf9473fa1f53a4f8225860e5897 + languageName: node + linkType: hard + "lower-case@npm:^2.0.2": version: 2.0.2 resolution: "lower-case@npm:2.0.2" @@ -3393,7 +3706,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.12, node-fetch@npm:^2.7.0": +"node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.7, node-fetch@npm:^2.7.0": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -3848,6 +4161,26 @@ __metadata: languageName: node linkType: hard +"protobufjs@npm:^7.2.5": + version: 7.3.2 + resolution: "protobufjs@npm:7.3.2" + dependencies: + "@protobufjs/aspromise": ^1.1.2 + "@protobufjs/base64": ^1.1.2 + "@protobufjs/codegen": ^2.0.4 + "@protobufjs/eventemitter": ^1.1.0 + "@protobufjs/fetch": ^1.1.0 + "@protobufjs/float": ^1.0.2 + "@protobufjs/inquire": ^1.1.0 + "@protobufjs/path": ^1.1.2 + "@protobufjs/pool": ^1.1.0 + "@protobufjs/utf8": ^1.1.0 + "@types/node": ">=13.7.0" + long: ^5.0.0 + checksum: cfb2a744787f26ee7c82f3e7c4b72cfc000e9bb4c07828ed78eb414db0ea97a340c0cc3264d0e88606592f847b12c0351411f10e9af255b7ba864eec44d7705f + languageName: node + linkType: hard + "proxy-addr@npm:^2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" @@ -4060,6 +4393,28 @@ __metadata: languageName: node linkType: hard +"rpc-websockets@npm:^9.0.0": + version: 9.0.1 + resolution: "rpc-websockets@npm:9.0.1" + dependencies: + "@swc/helpers": ^0.5.11 + "@types/uuid": ^8.3.4 + "@types/ws": ^8.2.2 + buffer: ^6.0.3 + bufferutil: ^4.0.1 + eventemitter3: ^5.0.1 + utf-8-validate: ^5.0.2 + uuid: ^8.3.2 + ws: ^8.5.0 + dependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: f268741ca904b7ab0845188a8cadd61b6872228a76eb3cedcd96be9bd8b9a3fab9113b0ff9a9c2a85179fa337cb52b1d48bdaeb21ff46bc71cdaae20cf80dc3b + languageName: node + linkType: hard + "rpc-websockets@npm:^9.0.2": version: 9.0.4 resolution: "rpc-websockets@npm:9.0.4" @@ -4434,6 +4789,13 @@ __metadata: languageName: node linkType: hard +"superstruct@npm:^1.0.3, superstruct@npm:^1.0.4": + version: 1.0.4 + resolution: "superstruct@npm:1.0.4" + checksum: 2e070994cc4998a753c3f0215449d6de01ffb8180e4f46527f559ffbc2ebcc40fcf428f545ccd355921ef2920db7d138a96258ae35c788e6c24b2aa8bb1695cb + languageName: node + linkType: hard + "superstruct@npm:^2.0.2": version: 2.0.2 resolution: "superstruct@npm:2.0.2" @@ -4591,6 +4953,13 @@ __metadata: languageName: node linkType: hard +"ts-log@npm:^2.2.7": + version: 2.2.7 + resolution: "ts-log@npm:2.2.7" + checksum: c423a5eb54abb9471578902953814d3d0c88b3f237db016998f8998ecf982cb0f748bb8ebf93670eeba9b836ff0ce407d8065a340f3ab218ea7b9442c255b3d4 + languageName: node + linkType: hard + "ts-node-dev@npm:^2.0.0": version: 2.0.0 resolution: "ts-node-dev@npm:2.0.0" @@ -5000,7 +5369,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.7.1": +"yargs@npm:^17.7.1, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: @@ -5021,3 +5390,10 @@ __metadata: checksum: 2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6 languageName: node linkType: hard + +"zod@npm:^3.23.8": + version: 3.25.76 + resolution: "zod@npm:3.25.76" + checksum: c9a403a62b329188a5f6bd24d5d935d2bba345f7ab8151d1baa1505b5da9f227fb139354b043711490c798e91f3df75991395e40142e6510a4b16409f302b849 + languageName: node + linkType: hard diff --git a/packages/monitor-service/Dockerfile b/packages/monitor-service/Dockerfile index 2a9fe34c3..0fd7a7dde 100644 --- a/packages/monitor-service/Dockerfile +++ b/packages/monitor-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/monitor-service/yarn.deploy.lock b/packages/monitor-service/yarn.deploy.lock index 481decced..387c6c4d3 100644 --- a/packages/monitor-service/yarn.deploy.lock +++ b/packages/monitor-service/yarn.deploy.lock @@ -14,6 +14,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/runtime@npm:7.24.7" + dependencies: + regenerator-runtime: ^0.14.0 + checksum: d17f29eed6f848ac15cdf4202a910b741facfb0419a9d79e5c7fa37df6362fc3227f1cc2e248cc6db5e53ddffb4caa6686c488e6e80ce3d29c36a4e74c8734ea + languageName: node + linkType: hard + "@babel/runtime@npm:^7.25.0": version: 7.26.0 resolution: "@babel/runtime@npm:7.26.0" @@ -53,6 +62,28 @@ __metadata: languageName: node linkType: hard +"@coral-xyz/anchor@npm:^0.29.0": + version: 0.29.0 + resolution: "@coral-xyz/anchor@npm:0.29.0" + dependencies: + "@coral-xyz/borsh": ^0.29.0 + "@noble/hashes": ^1.3.1 + "@solana/web3.js": ^1.68.0 + bn.js: ^5.1.2 + bs58: ^4.0.1 + buffer-layout: ^1.2.2 + camelcase: ^6.3.0 + cross-fetch: ^3.1.5 + crypto-hash: ^1.3.0 + eventemitter3: ^4.0.7 + pako: ^2.0.3 + snake-case: ^3.0.4 + superstruct: ^0.15.4 + toml: ^3.0.0 + checksum: 10c4e6c5557653419683f5ae22ec47ac266b64e5b422d466885cf2dc7efa8f836239bdf321495d3e2b3ce03e766667c0e2192cc573fbd66bc12cc652f5146e10 + languageName: node + linkType: hard + "@coral-xyz/anchor@npm:^0.31.0": version: 0.31.0 resolution: "@coral-xyz/anchor@npm:0.31.0" @@ -86,6 +117,18 @@ __metadata: languageName: node linkType: hard +"@coral-xyz/borsh@npm:^0.29.0": + version: 0.29.0 + resolution: "@coral-xyz/borsh@npm:0.29.0" + dependencies: + bn.js: ^5.1.2 + buffer-layout: ^1.2.0 + peerDependencies: + "@solana/web3.js": ^1.68.0 + checksum: 37006c75cd012672adf48e10234062624634da2a9335e34b7ff30969f58aff78cc3073b66a3edc806b52f038469f0c477a5a3ed35aaa075f3cbd44d7133ac218 + languageName: node + linkType: hard + "@coral-xyz/borsh@npm:^0.31.0": version: 0.31.0 resolution: "@coral-xyz/borsh@npm:0.31.0" @@ -150,6 +193,30 @@ __metadata: languageName: node linkType: hard +"@grpc/grpc-js@npm:^1.8.13": + version: 1.10.9 + resolution: "@grpc/grpc-js@npm:1.10.9" + dependencies: + "@grpc/proto-loader": ^0.7.13 + "@js-sdsl/ordered-map": ^4.4.2 + checksum: 88d91c227175275d8cc178c807d09510a83d947911c9bfe8ccd132cb27144c54508bcd114d52ab00b6e4f37eecf74aeee3ef3971900bdb90735d55a0b0dba761 + languageName: node + linkType: hard + +"@grpc/proto-loader@npm:^0.7.13": + version: 0.7.13 + resolution: "@grpc/proto-loader@npm:0.7.13" + dependencies: + lodash.camelcase: ^4.3.0 + long: ^5.0.0 + protobufjs: ^7.2.5 + yargs: ^17.7.2 + bin: + proto-loader-gen-types: build/bin/proto-loader-gen-types.js + checksum: 399c1b8a4627f93dc31660d9636ea6bf58be5675cc7581e3df56a249369e5be02c6cd0d642c5332b0d5673bc8621619bc06fb045aa3e8f57383737b5d35930dc + languageName: node + linkType: hard + "@helium/account-fetch-cache@^0.10.35": version: 0.0.0-use.local resolution: "@helium/account-fetch-cache@workspace:packages/account-fetch-cache" @@ -213,6 +280,8 @@ __metadata: "@helium/helium-sub-daos-sdk": ^0.10.35 "@helium/idls": ^0.10.35 "@helium/spl-utils": ^0.10.35 + "@pythnetwork/hermes-client": ^2.0.0 + "@pythnetwork/pyth-solana-receiver": ^0.10.2 bn.js: ^5.2.0 bs58: ^4.0.1 git-format-staged: ^2.1.3 @@ -506,6 +575,13 @@ __metadata: languageName: node linkType: hard +"@js-sdsl/ordered-map@npm:^4.4.2": + version: 4.4.2 + resolution: "@js-sdsl/ordered-map@npm:4.4.2" + checksum: a927ae4ff8565ecb75355cc6886a4f8fadbf2af1268143c96c0cce3ba01261d241c3f4ba77f21f3f017a00f91dfe9e0673e95f830255945c80a0e96c6d30508a + languageName: node + linkType: hard + "@metaplex-foundation/beet-solana@npm:0.4.0, @metaplex-foundation/beet-solana@npm:^0.4.0": version: 0.4.0 resolution: "@metaplex-foundation/beet-solana@npm:0.4.0" @@ -576,6 +652,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:^1.4.0": + version: 1.4.0 + resolution: "@noble/curves@npm:1.4.0" + dependencies: + "@noble/hashes": 1.4.0 + checksum: 0014ff561d16e98da4a57e2310a4015e4bdab3b1e1eafcd18d3f9b955c29c3501452ca5d702fddf8ca92d570bbeadfbe53fe16ebbd81a319c414f739154bb26b + languageName: node + linkType: hard + "@noble/curves@npm:^1.4.2": version: 1.8.0 resolution: "@noble/curves@npm:1.8.0" @@ -585,6 +670,13 @@ __metadata: languageName: node linkType: hard +"@noble/ed25519@npm:^1.7.1": + version: 1.7.3 + resolution: "@noble/ed25519@npm:1.7.3" + checksum: 45169927d51de513e47bbeebff3a603433c4ac7579e1b8c5034c380a0afedbe85e6959be3d69584a7a5ed6828d638f8f28879003b9bb2fb5f22d8aa2d88fd5fe + languageName: node + linkType: hard + "@noble/hashes@npm:1.3.2, @noble/hashes@npm:^1.3.1": version: 1.3.2 resolution: "@noble/hashes@npm:1.3.2" @@ -592,6 +684,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.3.0, @noble/hashes@npm:^1.4.0": + version: 1.4.0 + resolution: "@noble/hashes@npm:1.4.0" + checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 + languageName: node + linkType: hard + "@noble/hashes@npm:1.7.0": version: 1.7.0 resolution: "@noble/hashes@npm:1.7.0" @@ -599,13 +698,6 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:^1.4.0": - version: 1.4.0 - resolution: "@noble/hashes@npm:1.4.0" - checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 - languageName: node - linkType: hard - "@npmcli/fs@npm:^3.1.0": version: 3.1.0 resolution: "@npmcli/fs@npm:3.1.0" @@ -622,6 +714,125 @@ __metadata: languageName: node linkType: hard +"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/aspromise@npm:1.1.2" + checksum: 011fe7ef0826b0fd1a95935a033a3c0fd08483903e1aa8f8b4e0704e3233406abb9ee25350ec0c20bbecb2aad8da0dcea58b392bbd77d6690736f02c143865d2 + languageName: node + linkType: hard + +"@protobufjs/base64@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/base64@npm:1.1.2" + checksum: 67173ac34de1e242c55da52c2f5bdc65505d82453893f9b51dc74af9fe4c065cf4a657a4538e91b0d4a1a1e0a0642215e31894c31650ff6e3831471061e1ee9e + languageName: node + linkType: hard + +"@protobufjs/codegen@npm:^2.0.4": + version: 2.0.4 + resolution: "@protobufjs/codegen@npm:2.0.4" + checksum: 59240c850b1d3d0b56d8f8098dd04787dcaec5c5bd8de186fa548de86b86076e1c50e80144b90335e705a044edf5bc8b0998548474c2a10a98c7e004a1547e4b + languageName: node + linkType: hard + +"@protobufjs/eventemitter@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/eventemitter@npm:1.1.0" + checksum: 0369163a3d226851682f855f81413cbf166cd98f131edb94a0f67f79e75342d86e89df9d7a1df08ac28be2bc77e0a7f0200526bb6c2a407abbfee1f0262d5fd7 + languageName: node + linkType: hard + +"@protobufjs/fetch@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/fetch@npm:1.1.0" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.1" + "@protobufjs/inquire": "npm:^1.1.0" + checksum: 3fce7e09eb3f1171dd55a192066450f65324fd5f7cc01a431df01bb00d0a895e6bfb5b0c5561ce157ee1d886349c90703d10a4e11a1a256418ff591b969b3477 + languageName: node + linkType: hard + +"@protobufjs/float@npm:^1.0.2": + version: 1.0.2 + resolution: "@protobufjs/float@npm:1.0.2" + checksum: 5781e1241270b8bd1591d324ca9e3a3128d2f768077a446187a049e36505e91bc4156ed5ac3159c3ce3d2ba3743dbc757b051b2d723eea9cd367bfd54ab29b2f + languageName: node + linkType: hard + +"@protobufjs/inquire@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/inquire@npm:1.1.0" + checksum: ca06f02eaf65ca36fb7498fc3492b7fc087bfcc85c702bac5b86fad34b692bdce4990e0ef444c1e2aea8c034227bd1f0484be02810d5d7e931c55445555646f4 + languageName: node + linkType: hard + +"@protobufjs/path@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/path@npm:1.1.2" + checksum: 856eeb532b16a7aac071cacde5c5620df800db4c80cee6dbc56380524736205aae21e5ae47739114bf669ab5e8ba0e767a282ad894f3b5e124197cb9224445ee + languageName: node + linkType: hard + +"@protobufjs/pool@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/pool@npm:1.1.0" + checksum: d6a34fbbd24f729e2a10ee915b74e1d77d52214de626b921b2d77288bd8f2386808da2315080f2905761527cceffe7ec34c7647bd21a5ae41a25e8212ff79451 + languageName: node + linkType: hard + +"@protobufjs/utf8@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/utf8@npm:1.1.0" + checksum: f9bf3163d13aaa3b6f5e6fbf37a116e094ea021c0e1f2a7ccd0e12a29e2ce08dafba4e8b36e13f8ed7397e1591610ce880ed1289af4d66cf4ace8a36a9557278 + languageName: node + linkType: hard + +"@pythnetwork/hermes-client@npm:^2.0.0": + version: 2.0.0 + resolution: "@pythnetwork/hermes-client@npm:2.0.0" + dependencies: + "@zodios/core": ^10.9.6 + eventsource: ^3.0.5 + zod: ^3.23.8 + checksum: d5432c7c83617993a8e32fa4fde578e3b167ea348e5d3e2c681ee7bcf0e311824e00423d5529628f376f3541c888b9a12ed6c04135ea2e2f5872ab638a2dd31c + languageName: node + linkType: hard + +"@pythnetwork/price-service-sdk@npm:1.8.0": + version: 1.8.0 + resolution: "@pythnetwork/price-service-sdk@npm:1.8.0" + dependencies: + bn.js: ^5.2.1 + checksum: e843017db8469bc50c0e77b3db39c9756ff8d1c607a45626797ec4446121b9430770abcddcc15e08be132fa6081a5d872f0f79334cefceb7a1e7455300a1a426 + languageName: node + linkType: hard + +"@pythnetwork/pyth-solana-receiver@npm:^0.10.2": + version: 0.10.2 + resolution: "@pythnetwork/pyth-solana-receiver@npm:0.10.2" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@noble/hashes": ^1.4.0 + "@pythnetwork/price-service-sdk": 1.8.0 + "@pythnetwork/solana-utils": 0.4.5 + "@solana/web3.js": ^1.90.0 + checksum: 0b4376cb5c927d7571ca1b91216d47251a10aff52faf3d1581b8ac267facdb8214fedea7567e2266b2ba6f31cdb8ae44e6aa2ff7688f368c0582d4d59e89a287 + languageName: node + linkType: hard + +"@pythnetwork/solana-utils@npm:0.4.5": + version: 0.4.5 + resolution: "@pythnetwork/solana-utils@npm:0.4.5" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@solana/web3.js": ^1.90.0 + bs58: ^5.0.0 + jito-ts: ^3.0.1 + ts-log: ^2.2.7 + checksum: b877f2147a008403e13939b1b8e8a67d4d19432e46231b28c08d399010408093e9bad553ea2a7d7640496e37f1feac3e9fc01b8895f61c2d2617226a0d92d61e + languageName: node + linkType: hard + "@solana/buffer-layout-utils@npm:^0.2.0": version: 0.2.0 resolution: "@solana/buffer-layout-utils@npm:0.2.0" @@ -732,6 +943,52 @@ __metadata: languageName: node linkType: hard +"@solana/web3.js@npm:^1.90.0": + version: 1.93.0 + resolution: "@solana/web3.js@npm:1.93.0" + dependencies: + "@babel/runtime": ^7.24.7 + "@noble/curves": ^1.4.0 + "@noble/hashes": ^1.4.0 + "@solana/buffer-layout": ^4.0.1 + agentkeepalive: ^4.5.0 + bigint-buffer: ^1.1.5 + bn.js: ^5.2.1 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.0 + node-fetch: ^2.7.0 + rpc-websockets: ^9.0.0 + superstruct: ^1.0.4 + checksum: 3ae7d1e0cd998481b0d17076aec5df8c8593e7a9927ea245db19b18473abe3c96b94553de1f130ae1662a65a57b372a49025da38eeec598eb6c8ef355891b8b4 + languageName: node + linkType: hard + +"@solana/web3.js@npm:~1.77.3": + version: 1.77.4 + resolution: "@solana/web3.js@npm:1.77.4" + dependencies: + "@babel/runtime": ^7.12.5 + "@noble/curves": ^1.0.0 + "@noble/hashes": ^1.3.0 + "@solana/buffer-layout": ^4.0.0 + agentkeepalive: ^4.2.1 + bigint-buffer: ^1.1.5 + bn.js: ^5.0.0 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.0 + node-fetch: ^2.6.7 + rpc-websockets: ^7.5.1 + superstruct: ^0.14.2 + checksum: 7cd705244e83e74500ec3493b5d1743cc2c7d966c5775847baae356102602f65d35c5a2d9bca9a898bea0d05df057002b5c7660b9543ce7a8457442a20f24406 + languageName: node + linkType: hard + "@swc/helpers@npm:^0.5.11": version: 0.5.11 resolution: "@swc/helpers@npm:0.5.11" @@ -810,7 +1067,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*": +"@types/node@npm:*, @types/node@npm:>=13.7.0": version: 20.5.7 resolution: "@types/node@npm:20.5.7" checksum: fc284c8e16ddc04569730d58e87eae349eb1c3dd9020cb79a1862d9d9add6f04e7367a236f3252db8db2572f90278e250f4cd43d27d264972b54394eaba1ed76 @@ -881,6 +1138,16 @@ __metadata: languageName: node linkType: hard +"@zodios/core@npm:^10.9.6": + version: 10.9.6 + resolution: "@zodios/core@npm:10.9.6" + peerDependencies: + axios: ^0.x || ^1.0.0 + zod: ^3.x + checksum: 482a80bd4da661734f9ed276a92d9275fa1b76011bef26ede4a851e4c495d9103e6c9456074b9e50e4c89ad7e83fcead6ea45ffba615e6ff54b8088433ba47fc + languageName: node + linkType: hard + "JSONStream@npm:^1.3.5": version: 1.3.5 resolution: "JSONStream@npm:1.3.5" @@ -1192,7 +1459,7 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^5.1.0, bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": +"bn.js@npm:^5.0.0, bn.js@npm:^5.1.0, bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": version: 5.2.1 resolution: "bn.js@npm:5.2.1" checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 @@ -1407,6 +1674,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^8.0.1": + version: 8.0.1 + resolution: "cliui@npm:8.0.1" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^7.0.0" + checksum: 79648b3b0045f2e285b76fb2e24e207c6db44323581e421c3acbd0e86454cba1b37aea976ab50195a49e7384b871e6dfb2247ad7dec53c02454ac6497394cb56 + languageName: node + linkType: hard + "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -1560,7 +1838,7 @@ __metadata: languageName: node linkType: hard -"dotenv@npm:^16.3.1": +"dotenv@npm:^16.0.3, dotenv@npm:^16.3.1": version: 16.3.1 resolution: "dotenv@npm:16.3.1" checksum: 15d75e7279018f4bafd0ee9706593dd14455ddb71b3bcba9c52574460b7ccaf67d5cf8b2c08a5af1a9da6db36c956a04a1192b101ee102a3e0cf8817bbcf3dfd @@ -1699,6 +1977,13 @@ __metadata: languageName: node linkType: hard +"escalade@npm:^3.1.1": + version: 3.1.1 + resolution: "escalade@npm:3.1.1" + checksum: a3e2a99f07acb74b3ad4989c48ca0c3140f69f923e56d0cba0526240ee470b91010f9d39001f2a4a313841d237ede70a729e92125191ba5d21e74b106800b133 + languageName: node + linkType: hard + "eventemitter3@npm:^4.0.7": version: 4.0.7 resolution: "eventemitter3@npm:4.0.7" @@ -1720,6 +2005,22 @@ __metadata: languageName: node linkType: hard +"eventsource-parser@npm:^3.0.1": + version: 3.0.3 + resolution: "eventsource-parser@npm:3.0.3" + checksum: a052aaedb89da8744219aea539343dabc54c6e032acc47f182a90fbbb083583208fbe0f786d7bc1182da098c88a391b7881b59a3fc921a73b718f25d1ee37425 + languageName: node + linkType: hard + +"eventsource@npm:^3.0.5": + version: 3.0.7 + resolution: "eventsource@npm:3.0.7" + dependencies: + eventsource-parser: ^3.0.1 + checksum: cd8cbc3418238b9d751b6652edf442d4b869829fbc3b73444abca1816fe3d23dc707130dd9a990360bc27c281d986f2f62059d870921173425c3ac28d20a8414 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -1997,6 +2298,13 @@ __metadata: languageName: node linkType: hard +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 + languageName: node + linkType: hard + "get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.3": version: 1.2.1 resolution: "get-intrinsic@npm:1.2.1" @@ -2423,7 +2731,7 @@ __metadata: languageName: node linkType: hard -"jayson@npm:^4.1.0": +"jayson@npm:^4.0.0, jayson@npm:^4.1.0": version: 4.1.0 resolution: "jayson@npm:4.1.0" dependencies: @@ -2467,6 +2775,22 @@ __metadata: languageName: node linkType: hard +"jito-ts@npm:^3.0.1": + version: 3.0.1 + resolution: "jito-ts@npm:3.0.1" + dependencies: + "@grpc/grpc-js": ^1.8.13 + "@noble/ed25519": ^1.7.1 + "@solana/web3.js": ~1.77.3 + agentkeepalive: ^4.3.0 + dotenv: ^16.0.3 + jayson: ^4.0.0 + node-fetch: ^2.6.7 + superstruct: ^1.0.3 + checksum: bdacbba32601be1e1b6a9a96c9cf9ba6c16fc265da5f936295146099c3e86205ef46d67e771545452c1213a48de5008fcd3ce41c786afce03586d583a00f9319 + languageName: node + linkType: hard + "jmespath@npm:0.16.0": version: 0.16.0 resolution: "jmespath@npm:0.16.0" @@ -2529,6 +2853,13 @@ __metadata: languageName: node linkType: hard +"lodash.camelcase@npm:^4.3.0": + version: 4.3.0 + resolution: "lodash.camelcase@npm:4.3.0" + checksum: cb9227612f71b83e42de93eccf1232feeb25e705bdb19ba26c04f91e885bfd3dd5c517c4a97137658190581d3493ea3973072ca010aab7e301046d90740393d1 + languageName: node + linkType: hard + "lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" @@ -2536,6 +2867,13 @@ __metadata: languageName: node linkType: hard +"long@npm:^5.0.0": + version: 5.2.3 + resolution: "long@npm:5.2.3" + checksum: 885ede7c3de4facccbd2cacc6168bae3a02c3e836159ea4252c87b6e34d40af819824b2d4edce330bfb5c4d6e8ce3ec5864bdcf9473fa1f53a4f8225860e5897 + languageName: node + linkType: hard + "lower-case@npm:^2.0.2": version: 2.0.2 resolution: "lower-case@npm:2.0.2" @@ -2803,7 +3141,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.12, node-fetch@npm:^2.7.0": +"node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.7, node-fetch@npm:^2.7.0": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -3205,6 +3543,26 @@ __metadata: languageName: node linkType: hard +"protobufjs@npm:^7.2.5": + version: 7.3.2 + resolution: "protobufjs@npm:7.3.2" + dependencies: + "@protobufjs/aspromise": ^1.1.2 + "@protobufjs/base64": ^1.1.2 + "@protobufjs/codegen": ^2.0.4 + "@protobufjs/eventemitter": ^1.1.0 + "@protobufjs/fetch": ^1.1.0 + "@protobufjs/float": ^1.0.2 + "@protobufjs/inquire": ^1.1.0 + "@protobufjs/path": ^1.1.2 + "@protobufjs/pool": ^1.1.0 + "@protobufjs/utf8": ^1.1.0 + "@types/node": ">=13.7.0" + long: ^5.0.0 + checksum: cfb2a744787f26ee7c82f3e7c4b72cfc000e9bb4c07828ed78eb414db0ea97a340c0cc3264d0e88606592f847b12c0351411f10e9af255b7ba864eec44d7705f + languageName: node + linkType: hard + "proxy-addr@npm:^2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" @@ -3284,6 +3642,13 @@ __metadata: languageName: node linkType: hard +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: fb47e70bf0001fdeabdc0429d431863e9475e7e43ea5f94ad86503d918423c1543361cc5166d713eaa7029dd7a3d34775af04764bebff99ef413111a5af18c80 + languageName: node + linkType: hard + "require-from-string@npm:^2.0.2": version: 2.0.2 resolution: "require-from-string@npm:2.0.2" @@ -3393,6 +3758,28 @@ __metadata: languageName: node linkType: hard +"rpc-websockets@npm:^9.0.0": + version: 9.0.1 + resolution: "rpc-websockets@npm:9.0.1" + dependencies: + "@swc/helpers": ^0.5.11 + "@types/uuid": ^8.3.4 + "@types/ws": ^8.2.2 + buffer: ^6.0.3 + bufferutil: ^4.0.1 + eventemitter3: ^5.0.1 + utf-8-validate: ^5.0.2 + uuid: ^8.3.2 + ws: ^8.5.0 + dependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: f268741ca904b7ab0845188a8cadd61b6872228a76eb3cedcd96be9bd8b9a3fab9113b0ff9a9c2a85179fa337cb52b1d48bdaeb21ff46bc71cdaae20cf80dc3b + languageName: node + linkType: hard + "rpc-websockets@npm:^9.0.2": version: 9.0.4 resolution: "rpc-websockets@npm:9.0.4" @@ -3651,7 +4038,7 @@ __metadata: languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.3": +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -3728,6 +4115,13 @@ __metadata: languageName: node linkType: hard +"superstruct@npm:^1.0.3, superstruct@npm:^1.0.4": + version: 1.0.4 + resolution: "superstruct@npm:1.0.4" + checksum: 2e070994cc4998a753c3f0215449d6de01ffb8180e4f46527f559ffbc2ebcc40fcf428f545ccd355921ef2920db7d138a96258ae35c788e6c24b2aa8bb1695cb + languageName: node + linkType: hard + "superstruct@npm:^2.0.2": version: 2.0.2 resolution: "superstruct@npm:2.0.2" @@ -3865,6 +4259,13 @@ __metadata: languageName: node linkType: hard +"ts-log@npm:^2.2.7": + version: 2.2.7 + resolution: "ts-log@npm:2.2.7" + checksum: c423a5eb54abb9471578902953814d3d0c88b3f237db016998f8998ecf982cb0f748bb8ebf93670eeba9b836ff0ce407d8065a340f3ab218ea7b9442c255b3d4 + languageName: node + linkType: hard + "ts-node-dev@npm:^2.0.0": version: 2.0.0 resolution: "ts-node-dev@npm:2.0.0" @@ -4134,7 +4535,7 @@ __metadata: languageName: node linkType: hard -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" dependencies: @@ -4232,6 +4633,13 @@ __metadata: languageName: node linkType: hard +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 54f0fb95621ee60898a38c572c515659e51cc9d9f787fb109cef6fde4befbe1c4602dc999d30110feee37456ad0f1660fa2edcfde6a9a740f86a290999550d30 + languageName: node + linkType: hard + "yallist@npm:^4.0.0": version: 4.0.0 resolution: "yallist@npm:4.0.0" @@ -4239,9 +4647,38 @@ __metadata: languageName: node linkType: hard +"yargs-parser@npm:^21.1.1": + version: 21.1.1 + resolution: "yargs-parser@npm:21.1.1" + checksum: ed2d96a616a9e3e1cc7d204c62ecc61f7aaab633dcbfab2c6df50f7f87b393993fe6640d017759fe112d0cb1e0119f2b4150a87305cc873fd90831c6a58ccf1c + languageName: node + linkType: hard + +"yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: "npm:^8.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.3" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^21.1.1" + checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a + languageName: node + linkType: hard + "yn@npm:3.1.1": version: 3.1.1 resolution: "yn@npm:3.1.1" checksum: 2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6 languageName: node linkType: hard + +"zod@npm:^3.23.8": + version: 3.25.76 + resolution: "zod@npm:3.25.76" + checksum: c9a403a62b329188a5f6bd24d5d935d2bba345f7ab8151d1baa1505b5da9f227fb139354b043711490c798e91f3df75991395e40142e6510a4b16409f302b849 + languageName: node + linkType: hard diff --git a/packages/recent-helium-transactions-service/Dockerfile b/packages/recent-helium-transactions-service/Dockerfile index 3141f4a1a..93ecbb90c 100644 --- a/packages/recent-helium-transactions-service/Dockerfile +++ b/packages/recent-helium-transactions-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/rewards-oracle-faucet-service/Dockerfile b/packages/rewards-oracle-faucet-service/Dockerfile index 2a9fe34c3..0fd7a7dde 100644 --- a/packages/rewards-oracle-faucet-service/Dockerfile +++ b/packages/rewards-oracle-faucet-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/spl-utils/src/constants.ts b/packages/spl-utils/src/constants.ts index ac194f25d..f892880b5 100644 --- a/packages/spl-utils/src/constants.ts +++ b/packages/spl-utils/src/constants.ts @@ -25,6 +25,8 @@ export const HELIUM_COMMON_LUT = new PublicKey( "43eY9L2spbM2b1MPDFFBStUiFGt29ziZ1nc1xbpzsfVt" ); +export const HNT_PRICE_FEED_ID = "0x649fdd7ec08e8e2a20f425729854e90293dcbe2376abc47197a14da6ff339756" + export type Network = "hnt" | "mobile" | "iot"; export const networksToMint: { [Network: string]: PublicKey } = { hnt: HNT_MINT, diff --git a/packages/spl-utils/src/transaction.ts b/packages/spl-utils/src/transaction.ts index 63ae30dc7..0340e6588 100644 --- a/packages/spl-utils/src/transaction.ts +++ b/packages/spl-utils/src/transaction.ts @@ -559,8 +559,7 @@ export async function bulkSendTransactions( triesRemaining--; if (triesRemaining <= 0) { throw new Error( - `Failed to submit all txs after blockhashes expired, ${ - signedTxs.length - confirmedTxs.length + `Failed to submit all txs after blockhashes expired, ${signedTxs.length - confirmedTxs.length } remain` ); } @@ -637,7 +636,11 @@ export async function bulkSendRawTransactions( .filter(truthy); if (failures.length > 0) { - console.error(failures); + const failureIndexes = statuses.map((status, index) => status?.meta?.err ? index : null).filter(i => typeof i !== 'undefined'); + const failedTxs = await Promise.all(failureIndexes.map(index => connection.getTransaction(txids[index!], { commitment: "confirmed", maxSupportedTransactionVersion: 0 }))); + for (const tx of failedTxs) { + console.error(tx?.meta?.logMessages?.join("\n")); + } throw new Error("Failed to run txs"); } ret.push( diff --git a/packages/tokens-to-rent-service/Dockerfile b/packages/tokens-to-rent-service/Dockerfile index 2a9fe34c3..0fd7a7dde 100644 --- a/packages/tokens-to-rent-service/Dockerfile +++ b/packages/tokens-to-rent-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/tuktuk-pyth-service/Dockerfile b/packages/tuktuk-pyth-service/Dockerfile index 15dc2fa62..4568ced5b 100644 --- a/packages/tuktuk-pyth-service/Dockerfile +++ b/packages/tuktuk-pyth-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/packages/vsr-metadata-service/Dockerfile b/packages/vsr-metadata-service/Dockerfile index 2a9fe34c3..0fd7a7dde 100644 --- a/packages/vsr-metadata-service/Dockerfile +++ b/packages/vsr-metadata-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS BUILD_IMAGE +FROM node:22-alpine AS BUILD_IMAGE WORKDIR /usr/src/app @@ -16,7 +16,7 @@ COPY tsconfig.build.json tsconfig.json RUN yarn run build -FROM node:18-alpine +FROM node:22-alpine WORKDIR /usr/src/app diff --git a/programs/data-credits/src/instructions/initialize_data_credits_v0.rs b/programs/data-credits/src/instructions/initialize_data_credits_v0.rs index 142ca3da3..a93378125 100644 --- a/programs/data-credits/src/instructions/initialize_data_credits_v0.rs +++ b/programs/data-credits/src/instructions/initialize_data_credits_v0.rs @@ -6,7 +6,6 @@ use circuit_breaker::{ cpi::{accounts::InitializeMintWindowedBreakerV0, initialize_mint_windowed_breaker_v0}, CircuitBreaker, InitializeMintWindowedBreakerArgsV0, WindowedCircuitBreakerConfigV0, }; -use pyth_solana_receiver_sdk::price_update::PriceUpdateV2; use crate::state::*; @@ -27,7 +26,6 @@ pub struct InitializeDataCreditsV0<'info> { bump, )] pub data_credits: Box>, - pub hnt_price_oracle: Account<'info, PriceUpdateV2>, pub hnt_mint: Box>, /// CHECK: Initialized via cpi @@ -66,7 +64,6 @@ pub fn handler( ctx.accounts.data_credits.dc_mint = ctx.accounts.dc_mint.key(); ctx.accounts.data_credits.hnt_mint = ctx.accounts.hnt_mint.key(); ctx.accounts.data_credits.authority = args.authority; - ctx.accounts.data_credits.hnt_price_oracle = ctx.accounts.hnt_price_oracle.key(); ctx.accounts.data_credits.data_credits_bump = ctx.bumps.data_credits; diff --git a/programs/data-credits/src/instructions/mint_data_credits_v0.rs b/programs/data-credits/src/instructions/mint_data_credits_v0.rs index 21bfa631e..07f497be0 100644 --- a/programs/data-credits/src/instructions/mint_data_credits_v0.rs +++ b/programs/data-credits/src/instructions/mint_data_credits_v0.rs @@ -21,6 +21,11 @@ pub struct MintDataCreditsArgsV0 { pub const TESTING: bool = std::option_env!("TESTING").is_some(); +pub const HNT_PRICE_FEED_ID: [u8; 32] = [ + 0x64, 0x9f, 0xdd, 0x7e, 0xc0, 0x8e, 0x8e, 0x2a, 0x20, 0xf4, 0x25, 0x72, 0x98, 0x54, 0xe9, 0x02, + 0x93, 0xdc, 0xbe, 0x23, 0x76, 0xab, 0xc4, 0x71, 0x97, 0xa1, 0x4d, 0xa6, 0xff, 0x33, 0x97, 0x56, +]; + #[derive(Accounts)] #[instruction(args: MintDataCreditsArgsV0)] pub struct MintDataCreditsV0<'info> { @@ -31,13 +36,13 @@ pub struct MintDataCreditsV0<'info> { ], bump = data_credits.data_credits_bump, has_one = hnt_mint, - has_one = hnt_price_oracle )] pub data_credits: Box>, /// CHECK: Checked by loading with pyth. Also double checked by the has_one on data credits instance. #[account( constraint = hnt_price_oracle.verification_level == VerificationLevel::Full @ DataCreditsErrors::PythPriceFeedStale, + constraint = hnt_price_oracle.price_message.feed_id == HNT_PRICE_FEED_ID, )] pub hnt_price_oracle: Account<'info, PriceUpdateV2>, diff --git a/programs/data-credits/src/instructions/update_data_credits_v0.rs b/programs/data-credits/src/instructions/update_data_credits_v0.rs index 73b298c11..e1cfb92c6 100644 --- a/programs/data-credits/src/instructions/update_data_credits_v0.rs +++ b/programs/data-credits/src/instructions/update_data_credits_v0.rs @@ -1,11 +1,11 @@ -use crate::state::*; use anchor_lang::prelude::*; use anchor_spl::token::Mint; +use crate::state::*; + #[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)] pub struct UpdateDataCreditsArgsV0 { new_authority: Option, - hnt_price_oracle: Option, } #[derive(Accounts)] @@ -27,9 +27,5 @@ pub fn handler(ctx: Context, args: UpdateDataCreditsArgsV0) ctx.accounts.data_credits.authority = new_authority; } - if let Some(hnt_price_oracle) = args.hnt_price_oracle { - ctx.accounts.data_credits.hnt_price_oracle = hnt_price_oracle; - } - Ok(()) } diff --git a/programs/dc-auto-top/src/instructions/top_off_v0.rs b/programs/dc-auto-top/src/instructions/top_off_v0.rs index 4c68c63b1..d803177f4 100644 --- a/programs/dc-auto-top/src/instructions/top_off_v0.rs +++ b/programs/dc-auto-top/src/instructions/top_off_v0.rs @@ -48,9 +48,6 @@ pub struct TopOffV0<'info> { has_one = escrow_account, )] pub delegated_data_credits: Box>, - #[account( - has_one = hnt_price_oracle - )] pub data_credits: Box>, #[account(mut)] pub dc_mint: Box>, diff --git a/programs/helium-entity-manager/src/instructions/onboard_data_only_mobile_hotspot_v0.rs b/programs/helium-entity-manager/src/instructions/onboard_data_only_mobile_hotspot_v0.rs index 7217f1443..1aed0080d 100644 --- a/programs/helium-entity-manager/src/instructions/onboard_data_only_mobile_hotspot_v0.rs +++ b/programs/helium-entity-manager/src/instructions/onboard_data_only_mobile_hotspot_v0.rs @@ -18,7 +18,7 @@ use data_credits::{ use helium_sub_daos::{program::HeliumSubDaos, DaoV0, SubDaoV0}; use shared_utils::*; -use crate::{error::ErrorCode, hash_entity_key, state::*, TESTING}; +use crate::{error::ErrorCode, hash_entity_key, state::*}; #[derive(AnchorSerialize, AnchorDeserialize, Clone)] pub struct OnboardDataOnlyMobileHotspotArgsV0 { diff --git a/programs/hpl-crons/src/instructions/queue_end_epoch.rs b/programs/hpl-crons/src/instructions/queue_end_epoch.rs index 3c8539f3e..d77f8c882 100644 --- a/programs/hpl-crons/src/instructions/queue_end_epoch.rs +++ b/programs/hpl-crons/src/instructions/queue_end_epoch.rs @@ -9,7 +9,7 @@ use spl_token::solana_program::instruction::Instruction; use tuktuk_program::{ compile_transaction, write_return_tasks::{write_return_tasks, AccountWithSeeds, PayerInfo, WriteReturnTasksArgs}, - RunTaskReturnV0, TaskQueueV0, TaskReturnV0, TransactionSourceV0, TriggerV0, + RunTaskReturnV0, TaskReturnV0, TransactionSourceV0, TriggerV0, }; use crate::{hpl_crons::CIRCUIT_BREAKER_PROGRAM, EpochTrackerV0, EPOCH_LENGTH}; diff --git a/programs/welcome-pack/src/instructions/claim_welcome_pack_v0.rs b/programs/welcome-pack/src/instructions/claim_welcome_pack_v0.rs index 13034379f..a000f9490 100644 --- a/programs/welcome-pack/src/instructions/claim_welcome_pack_v0.rs +++ b/programs/welcome-pack/src/instructions/claim_welcome_pack_v0.rs @@ -289,12 +289,12 @@ pub fn handler<'info>( ScheduleTaskV0 { payer: ctx.accounts.claimer.to_account_info(), mini_fanout: ctx.accounts.rewards_recipient.to_account_info(), - next_task: ctx.accounts.system_program.to_account_info(), + next_task: ctx.accounts.mini_fanout_program.to_account_info(), queue_authority: ctx.accounts.queue_authority.to_account_info(), task_queue_authority: ctx.accounts.task_queue_authority.to_account_info(), task_queue: ctx.accounts.task_queue.to_account_info(), task: ctx.accounts.task.to_account_info(), - next_pre_task: ctx.accounts.system_program.to_account_info(), + next_pre_task: ctx.accounts.mini_fanout_program.to_account_info(), pre_task: ctx.accounts.pre_task.to_account_info(), tuktuk_program: ctx.accounts.tuktuk_program.to_account_info(), system_program: ctx.accounts.system_program.to_account_info(), diff --git a/tests/data-credits.ts b/tests/data-credits.ts index 21c9276d4..cb7ffd5da 100644 --- a/tests/data-credits.ts +++ b/tests/data-credits.ts @@ -3,10 +3,6 @@ import { Program } from "@coral-xyz/anchor"; import { Keypair as HeliumKeypair } from "@helium/crypto"; import { VoterStakeRegistry } from "@helium/idls/lib/types/voter_stake_registry"; import { createAtaAndMint, createMint } from "@helium/spl-utils"; -import { - PythSolanaReceiver, - pythSolanaReceiverIdl, -} from "@helium/currency-utils"; import { createAssociatedTokenAccountIdempotentInstruction, getAccount, @@ -23,6 +19,7 @@ import { delegatedDataCreditsKey, escrowAccountKey, init, + mintDataCredits, } from "../packages/data-credits-sdk/src"; import { PROGRAM_ID } from "../packages/data-credits-sdk/src/constants"; import * as hsd from "../packages/helium-sub-daos-sdk/src"; @@ -84,7 +81,6 @@ describe("data-credits", () => { let hsdProgram: Program; let vsrProgram: Program; let nftProxyProgram: Program; - let pythProgram: Program; let dcKey: PublicKey; let hntMint: PublicKey; let dcMint: PublicKey; @@ -96,9 +92,6 @@ describe("data-credits", () => { const me = provider.wallet.publicKey; before(async () => { - pythProgram = new Program( - pythSolanaReceiverIdl as any, - ); program = await init( provider, PROGRAM_ID, @@ -148,9 +141,6 @@ describe("data-credits", () => { hntMint, dcMint, payer: me, - hntPriceOracle: new PublicKey( - "4DdmDswskDxXGpwHrXUfn2CNUm9rt21ac79GHNTN3J33" - ), }); dcKey = (await method.pubkeys()).dataCredits!; await method.rpc({ @@ -235,13 +225,14 @@ describe("data-credits", () => { }); it("mints some data credits with hnt amount", async () => { - await program.methods - .mintDataCreditsV0({ - hntAmount: new BN(1 * 10 ** 8), - dcAmount: null, - }) - .accountsPartial({ dcMint }) - .rpc({ skipPreflight: true }); + const { txs, priceUpdates } = await mintDataCredits({ + dcMint, + program, + hntAmount: new BN(1 * 10 ** 8), + }); + console.log('txs', JSON.stringify(txs, null, 2)); + + await provider.sendAll(txs, { skipPreflight: true }) const dcAta = await getAssociatedTokenAddress(dcMint, me); const dcAtaAcc = await getAccount(provider.connection, dcAta); @@ -249,18 +240,15 @@ describe("data-credits", () => { assert(dcAtaAcc.isFrozen); const dcBal = await provider.connection.getTokenAccountBalance(dcAta); const hntBal = await provider.connection.getTokenAccountBalance(hntAta); - const price = await pythProgram.account.priceUpdateV2.fetch( - new PublicKey("4DdmDswskDxXGpwHrXUfn2CNUm9rt21ac79GHNTN3J33") - ); - console.log(price); + const price = priceUpdates.parsed![0]; const approxEndBal = startDcBal + Math.floor( - price.priceMessage.emaPrice - .sub(price.priceMessage.emaConf.mul(new BN(2))) + new BN(price.ema_price.price) + .sub(new BN(price.ema_price.conf).mul(new BN(2))) .toNumber() * - 10 ** price.priceMessage.exponent * + 10 ** price.ema_price.expo * 10 ** 5 ); expect(dcBal.value.uiAmount).to.be.within( @@ -272,13 +260,13 @@ describe("data-credits", () => { it("mints some data credits with dc amount", async () => { let dcAmount = 1428 * 10 ** 5; - await program.methods - .mintDataCreditsV0({ - hntAmount: null, - dcAmount: new BN(dcAmount), - }) - .accountsPartial({ dcMint }) - .rpc({ skipPreflight: true }); + const { txs, priceUpdates } = await mintDataCredits({ + dcMint, + program, + dcAmount: new BN(dcAmount), + }); + + await provider.sendAll(txs) const dcAta = await getAssociatedTokenAddress(dcMint, me); const dcAtaAcc = await getAccount(provider.connection, dcAta); @@ -289,14 +277,12 @@ describe("data-credits", () => { await getAssociatedTokenAddress(hntMint, me) ); - const price = await pythProgram.account.priceUpdateV2.fetch( - new PublicKey("4DdmDswskDxXGpwHrXUfn2CNUm9rt21ac79GHNTN3J33") - ); + const price = priceUpdates.parsed![0]; const hntEmaPrice = - price.priceMessage.emaPrice - .sub(price.priceMessage.emaConf.mul(new BN(2))) + new BN(price.ema_price.price) + .sub(new BN(price.ema_price.conf).mul(new BN(2))) .toNumber() * - 10 ** price.priceMessage.exponent; + 10 ** price.ema_price.expo; const hntAmount = (Math.floor(dcAmount * 10 ** (hntDecimals - 5)) / hntEmaPrice) * 10 ** -hntDecimals; @@ -340,7 +326,6 @@ describe("data-credits", () => { await program.methods .updateDataCreditsV0({ newAuthority: PublicKey.default, - hntPriceOracle: null, }) .accountsPartial({ dcMint, diff --git a/tests/dc-auto-topoff.ts b/tests/dc-auto-topoff.ts index 9e0956313..a08b74f3d 100644 --- a/tests/dc-auto-topoff.ts +++ b/tests/dc-auto-topoff.ts @@ -1,10 +1,6 @@ import * as anchor from "@coral-xyz/anchor"; import { Program } from "@coral-xyz/anchor"; import { Keypair as HeliumKeypair } from "@helium/crypto"; -import { - PythSolanaReceiver, - pythSolanaReceiverIdl, -} from "@helium/currency-utils"; import { dataCreditsKey, delegatedDataCreditsKey, init as initDataCredits } from "@helium/data-credits-sdk"; import { init as initHem } from "@helium/helium-entity-manager-sdk"; import { daoKey, init as initHsd } from "@helium/helium-sub-daos-sdk"; @@ -67,7 +63,6 @@ describe("dc-auto-topoff", () => { let dcMint: PublicKey; let routerKey: string; let subDao: PublicKey; - let pythProgram: Program; const tuktukConfig: PublicKey = tuktukConfigKey()[0]; const queueAuthority = queueAuthorityKey()[0] @@ -81,9 +76,6 @@ describe("dc-auto-topoff", () => { hsdProgram = await initHsd(provider) program = await init(provider); tuktukProgram = await initTuktuk(provider); - pythProgram = new Program( - pythSolanaReceiverIdl as any, - ); dcProgram = await initDataCredits(provider); const config = await tuktukProgram.account.tuktukConfigV0.fetch( tuktukConfig @@ -224,6 +216,7 @@ describe("dc-auto-topoff", () => { newTaskId: nextTask, newPythTaskId: nextPythTask, schedule: "0 0 * * * *", + threshold: new anchor.BN(10000000), }) .preInstructions([ ComputeBudgetProgram.setComputeUnitLimit({ units: 1400000 }), diff --git a/tests/distributor-oracle.ts b/tests/distributor-oracle.ts index 05bca7f4c..ff56cda1d 100644 --- a/tests/distributor-oracle.ts +++ b/tests/distributor-oracle.ts @@ -82,6 +82,11 @@ chai.use(chaiHttp); export class DatabaseMock implements Database { dao: PublicKey; + readonly hemProgram: Program; + readonly getAssetFn: ( + url: string, + asset: PublicKey + ) => Promise; inMemHash: { totalClicks: number; lifetimeRewards: number; @@ -94,13 +99,15 @@ export class DatabaseMock implements Database { }; constructor( - readonly hemProgram: Program, - readonly getAssetFn: ( + hemProgram: Program, + getAssetFn: ( url: string, asset: PublicKey ) => Promise = getAsset, dao: PublicKey ) { + this.hemProgram = hemProgram; + this.getAssetFn = getAssetFn; this.dao = dao; this.inMemHash = { totalClicks: 0, diff --git a/tests/helium-entity-manager.ts b/tests/helium-entity-manager.ts index 8d4a657de..ad3405c67 100644 --- a/tests/helium-entity-manager.ts +++ b/tests/helium-entity-manager.ts @@ -1,7 +1,7 @@ import * as anchor from "@coral-xyz/anchor"; import { Program } from "@coral-xyz/anchor"; import { Keypair as HeliumKeypair } from "@helium/crypto"; -import { init as initDataCredits } from "@helium/data-credits-sdk"; +import { init as initDataCredits, mintDataCredits } from "@helium/data-credits-sdk"; import { init as initHeliumSubDaos } from "@helium/helium-sub-daos-sdk"; import { notEmittedKey, init as initBurn } from "@helium/no-emit-sdk"; import { @@ -328,13 +328,13 @@ describe("helium-entity-manager", () => { hotspotOwner: hotspotOwner.publicKey, })); - await dcProgram.methods - .mintDataCreditsV0({ + await provider.sendAll( + (await mintDataCredits({ + program: dcProgram, hntAmount: toBN(startDcBal, 8), - dcAmount: null, - }) - .accountsPartial({ dcMint }) - .rpc({ skipPreflight: true }); + dcMint, + })).txs + ); }); it("issues and onboards an iot data only hotspot", async () => { let hotspotOwner = Keypair.generate(); @@ -735,13 +735,13 @@ describe("helium-entity-manager", () => { await initTestMaker(hemProgram, provider, rewardableEntityConfig, dao); - await dcProgram.methods - .mintDataCreditsV0({ + await provider.sendAll( + (await mintDataCredits({ + program: dcProgram, hntAmount: toBN(startDcBal, 8), - dcAmount: null, - }) - .accountsPartial({ dcMint }) - .rpc({ skipPreflight: true }); + dcMint, + })).txs + ); maker = makerConf.maker; makerKeypair = makerConf.makerKeypair; @@ -917,14 +917,14 @@ describe("helium-entity-manager", () => { ({ mobileInfo: infoKey } = await method.pubkeys()); await method.rpc({ skipPreflight: true }); - - await dcProgram.methods - .mintDataCreditsV0({ + await provider.sendAll( + (await mintDataCredits({ + program: dcProgram, hntAmount: toBN(startDcBal, 8), - dcAmount: null, - }) - .accountsPartial({ dcMint, recipient: hotspotOwner.publicKey }) - .rpc(); + dcMint, + recipient: hotspotOwner.publicKey, + })).txs + ); }); it("onboarding fees be backpaid with DC when subdao fees are raised", async () => { @@ -1103,13 +1103,13 @@ describe("helium-entity-manager", () => { await initTestMaker(hemProgram, provider, rewardableEntityConfig, dao); - await dcProgram.methods - .mintDataCreditsV0({ + await provider.sendAll( + (await mintDataCredits({ + program: dcProgram, hntAmount: toBN(startDcBal, 8), - dcAmount: null, - }) - .accountsPartial({ dcMint: dcMint }) - .rpc({ skipPreflight: true }); + dcMint, + })).txs + ); maker = makerConf.maker; makerKeypair = makerConf.makerKeypair; @@ -1225,13 +1225,14 @@ describe("helium-entity-manager", () => { await method.rpc({ skipPreflight: true }); - await dcProgram.methods - .mintDataCreditsV0({ + await provider.sendAll( + (await mintDataCredits({ + program: dcProgram, hntAmount: toBN(startDcBal, 8), - dcAmount: null, - }) - .accountsPartial({ dcMint, recipient: hotspotOwner.publicKey }) - .rpc(); + dcMint, + recipient: hotspotOwner.publicKey, + })).txs + ); }); it("oracle can update active status", async () => { diff --git a/tests/helium-sub-daos.ts b/tests/helium-sub-daos.ts index b982b798a..7a1b8c205 100644 --- a/tests/helium-sub-daos.ts +++ b/tests/helium-sub-daos.ts @@ -34,7 +34,7 @@ import { import { BN } from "bn.js"; import chai, { assert, expect } from "chai"; import chaiAsPromised from "chai-as-promised"; -import { init as dcInit } from "../packages/data-credits-sdk/src"; +import { init as dcInit, mintDataCredits } from "../packages/data-credits-sdk/src"; import { init as issuerInit, onboardIotHotspot, @@ -211,13 +211,13 @@ describe("helium-sub-daos", () => { async function burnDc( amount: number ): Promise<{ subDaoEpochInfo: PublicKey }> { - await dcProgram.methods - .mintDataCreditsV0({ + await provider.sendAll( + (await mintDataCredits({ + program: dcProgram, hntAmount: toBN(amount, 8), - dcAmount: null, - }) - .accountsPartial({ dcMint }) - .rpc({ skipPreflight: true }); + dcMint, + })).txs + ); await sendInstructions(provider, [ SystemProgram.transfer({ @@ -606,14 +606,13 @@ describe("helium-sub-daos", () => { .signers([makerKeypair, eccVerifier]); await issueMethod.rpc({ skipPreflight: true }); - await dcProgram.methods - .mintDataCreditsV0({ - // $50 onboard, $10 location assert + await provider.sendAll( + (await mintDataCredits({ + program: dcProgram, dcAmount: toBN(60, 5), - hntAmount: null, - }) - .accountsPartial({ dcMint }) - .rpc({ skipPreflight: true }); + dcMint, + })).txs + ); const method = ( await onboardIotHotspot({ diff --git a/tests/hexboosting.ts b/tests/hexboosting.ts index 2f48df8c5..0dffcbe7b 100644 --- a/tests/hexboosting.ts +++ b/tests/hexboosting.ts @@ -1,6 +1,6 @@ import * as anchor from "@coral-xyz/anchor"; import { Program } from "@coral-xyz/anchor"; -import { init as initDataCredits } from "@helium/data-credits-sdk"; +import { init as initDataCredits, mintDataCredits } from "@helium/data-credits-sdk"; import { init as initHeliumSubDaos } from "@helium/helium-sub-daos-sdk"; import { Hexboosting } from "@helium/idls/lib/types/hexboosting"; import { MobileEntityManager } from "@helium/idls/lib/types/mobile_entity_manager"; @@ -99,16 +99,14 @@ describe("hexboosting", () => { const dataCredits = await initTestDataCredits(dcProgram, provider); const hntMint = await createMint(provider, 8, me, me); await createAtaAndMint(provider, hntMint, new BN("100000000000000"), me); - await dcProgram.methods - .mintDataCreditsV0({ + await provider.sendAll( + (await mintDataCredits({ + program: dcProgram, dcAmount: new BN("10000000000"), - hntAmount: null, - }) - .accountsPartial({ dcMint: dataCredits.dcMint, - recipient: me, - }) - .rpc({ skipPreflight: true }); + })).txs + ); + const { dao } = await initTestDao( hsdProgram, provider, diff --git a/tests/utils/fixtures.ts b/tests/utils/fixtures.ts index 45ff7e852..f82dbc646 100644 --- a/tests/utils/fixtures.ts +++ b/tests/utils/fixtures.ts @@ -76,9 +76,6 @@ export const initTestDataCredits = async ( .accountsPartial({ hntMint, dcMint, - hntPriceOracle: new PublicKey( - "4DdmDswskDxXGpwHrXUfn2CNUm9rt21ac79GHNTN3J33" - ), }); const dcKey = (await initDataCredits.pubkeys()).dataCredits!; diff --git a/tests/welcome-pack.ts b/tests/welcome-pack.ts index a6acb0c3c..1413fe721 100644 --- a/tests/welcome-pack.ts +++ b/tests/welcome-pack.ts @@ -290,6 +290,7 @@ describe("welcome-pack", () => { }) getAssetFn = mock.getAssetFn getAssetProofFn = mock.getAssetProofFn + console.log("getting ixns") const ixs = [ ComputeBudgetProgram.setComputeUnitLimit({ units: 1000000 }), await (await claimWelcomePack({ @@ -305,7 +306,9 @@ describe("welcome-pack", () => { })) .instruction() ] + console.log("ixns got") const slot = await provider.connection.getSlot(); + console.log("creating lut") const [lutIx, lut] = AddressLookupTableProgram.createLookupTable({ authority: me, payer: me, @@ -317,15 +320,17 @@ describe("welcome-pack", () => { lookupTable: lut, addresses: [taskQueue, hntMint, ASSOCIATED_PROGRAM_ID, BUBBLEGUM_PROGRAM_ID, NOOP_PROGRAM_ID], })]) + console.log("lut created") // Wait for lut to activate await sleep(1000) + console.log("sending ixs") await bulkSendTransactions(provider, [{ instructions: ixs, addressLookupTableAddresses: [lut], feePayer: me, signers: [claimer], }], undefined, 10, [claimer]) - + console.log("ixns sent") // Verify mini fanout was created const miniFanoutAccount = await miniFanoutProgram.account.miniFanoutV0.fetch(miniFanout) expect(miniFanoutAccount.schedule).to.equal(rewardsSchedule) diff --git a/yarn.lock b/yarn.lock index cea30d673..4f85f4502 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1011,6 +1011,8 @@ __metadata: version: 0.0.0-use.local resolution: "@helium/currency-utils@workspace:packages/currency-utils" dependencies: + "@helium/spl-utils": ^0.10.35 + "@pythnetwork/hermes-client": ^2.0.0 "@solana/spl-token": ^0.3.8 "@solana/web3.js": ^1.91.1 languageName: unknown @@ -1026,6 +1028,8 @@ __metadata: "@helium/helium-sub-daos-sdk": ^0.10.35 "@helium/idls": ^0.10.35 "@helium/spl-utils": ^0.10.35 + "@pythnetwork/hermes-client": ^2.0.0 + "@pythnetwork/pyth-solana-receiver": ^0.10.2 bn.js: ^5.2.0 bs58: ^4.0.1 git-format-staged: ^2.1.3 @@ -3914,6 +3918,19 @@ __metadata: languageName: node linkType: hard +"@pythnetwork/pyth-solana-receiver@npm:^0.10.2": + version: 0.10.2 + resolution: "@pythnetwork/pyth-solana-receiver@npm:0.10.2" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@noble/hashes": ^1.4.0 + "@pythnetwork/price-service-sdk": 1.8.0 + "@pythnetwork/solana-utils": 0.4.5 + "@solana/web3.js": ^1.90.0 + checksum: 0b4376cb5c927d7571ca1b91216d47251a10aff52faf3d1581b8ac267facdb8214fedea7567e2266b2ba6f31cdb8ae44e6aa2ff7688f368c0582d4d59e89a287 + languageName: node + linkType: hard + "@pythnetwork/pyth-solana-receiver@npm:^0.11.0": version: 0.11.0 resolution: "@pythnetwork/pyth-solana-receiver@npm:0.11.0" @@ -3952,6 +3969,19 @@ __metadata: languageName: node linkType: hard +"@pythnetwork/solana-utils@npm:0.4.5": + version: 0.4.5 + resolution: "@pythnetwork/solana-utils@npm:0.4.5" + dependencies: + "@coral-xyz/anchor": ^0.29.0 + "@solana/web3.js": ^1.90.0 + bs58: ^5.0.0 + jito-ts: ^3.0.1 + ts-log: ^2.2.7 + checksum: b877f2147a008403e13939b1b8e8a67d4d19432e46231b28c08d399010408093e9bad553ea2a7d7640496e37f1feac3e9fc01b8895f61c2d2617226a0d92d61e + languageName: node + linkType: hard + "@pythnetwork/solana-utils@npm:0.5.0": version: 0.5.0 resolution: "@pythnetwork/solana-utils@npm:0.5.0" From 8bb98ec03d23b8b20c7a14864fdbd3b037943cfd Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Wed, 17 Sep 2025 09:19:43 -0700 Subject: [PATCH 10/10] Cargo bump --- Cargo.lock | 6 +++--- programs/data-credits/Cargo.toml | 2 +- programs/mini-fanout/Cargo.toml | 2 +- programs/welcome-pack/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18ff9451f..6ccb3f514 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -697,7 +697,7 @@ dependencies = [ [[package]] name = "data-credits" -version = "0.2.5" +version = "0.2.6" dependencies = [ "anchor-lang", "anchor-spl", @@ -1228,7 +1228,7 @@ dependencies = [ [[package]] name = "mini-fanout" -version = "0.1.2" +version = "0.1.3" dependencies = [ "anchor-lang", "anchor-spl", @@ -3436,7 +3436,7 @@ dependencies = [ [[package]] name = "welcome-pack" -version = "0.0.1" +version = "0.0.2" dependencies = [ "account-compression-cpi", "anchor-lang", diff --git a/programs/data-credits/Cargo.toml b/programs/data-credits/Cargo.toml index ee005e253..e4ce10247 100644 --- a/programs/data-credits/Cargo.toml +++ b/programs/data-credits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "data-credits" -version = "0.2.5" +version = "0.2.6" # Trigger deployment - timestamp: 03-31-2025 #3 description = "Created with Anchor" edition = "2021" diff --git a/programs/mini-fanout/Cargo.toml b/programs/mini-fanout/Cargo.toml index fb72c49a3..aeb578127 100644 --- a/programs/mini-fanout/Cargo.toml +++ b/programs/mini-fanout/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mini-fanout" -version = "0.1.2" +version = "0.1.3" # Trigger deployment - timestamp: 03-31-2025 #3 description = "Created with Anchor" edition = "2021" diff --git a/programs/welcome-pack/Cargo.toml b/programs/welcome-pack/Cargo.toml index 1e7c42c24..f41ea1269 100644 --- a/programs/welcome-pack/Cargo.toml +++ b/programs/welcome-pack/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "welcome-pack" -version = "0.0.1" +version = "0.0.2" description = "Created with Anchor" edition = "2021"