diff --git a/Anchor.toml b/Anchor.toml index 394eaaea1..fb3f09759 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -17,6 +17,7 @@ fanout = "fanqeMu3fw8R4LwKNbahPtYXJsyLL6NXyfe2BqzhfB6" mobile_entity_manager = "memMa1HG4odAFmUbGWfPwS1WWfK95k99F2YTkGvyxZr" hexboosting = "hexbnKYoA2GercNNhHUCCfrTRWrHjT6ujKPXTa5NPqJ" no_emit = "noEmmgLmQdk6DLiPV8CSwQv3qQDyGEhz9m5A4zhtByv" +iot_routing_manager = "irtjLnjCMmyowq2m3KWqpuFB3M9gdNA9A4t4d6VWmzB" [workspace] members = [ @@ -34,6 +35,7 @@ members = [ "programs/mobile-entity-manager", "programs/hexboosting", "programs/no-emit", + "programs/iot-routing-manager", ] [registry] @@ -79,6 +81,9 @@ address = "66t3XARU6Ja3zj91gDZ2KoNLJHEMTYPSKqJWYb6PJJBA" # Proposal IDL [[test.validator.clone]] address = "DQ4C1tzvu28cwo1roN1Wm6TW35sfJEjLh517k3ZeWevx" # Mobile price oracle +[[test.validator.clone]] +address = "8UYEn5Weq7toHwgcmctvcAxaNJo3SJxXEayM57rpoXr9" # IOT price oracle + # Pyth price oracle [[test.validator.clone]] address = "4DdmDswskDxXGpwHrXUfn2CNUm9rt21ac79GHNTN3J33" diff --git a/Cargo.lock b/Cargo.lock index d7ad9f9bd..f91c0e0ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2238,6 +2238,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "iot-routing-manager" +version = "0.1.2" +dependencies = [ + "account-compression-cpi", + "anchor-lang", + "anchor-spl", + "angry-purple-tiger", + "bs58 0.3.1", + "bubblegum-cpi", + "bytemuck", + "default-env", + "helium-entity-manager", + "helium-sub-daos", + "mpl-token-metadata", + "pyth-solana-receiver-sdk", + "shared-utils", + "solana-program", + "solana-security-txt", +] + [[package]] name = "ipnet" version = "2.8.0" diff --git a/packages/anchor-resolvers/src/heliumCommonResolver.ts b/packages/anchor-resolvers/src/heliumCommonResolver.ts index 1ec207865..a78dad512 100644 --- a/packages/anchor-resolvers/src/heliumCommonResolver.ts +++ b/packages/anchor-resolvers/src/heliumCommonResolver.ts @@ -28,6 +28,8 @@ export const heliumCommonResolver = resolveIndividual(async ({ path }) => { return new PublicKey("1azyuavdMyvsivtNxPoz6SucD18eDHeXzFCUPq5XU7w"); case "noEmitProgram": return new PublicKey("noEmmgLmQdk6DLiPV8CSwQv3qQDyGEhz9m5A4zhtByv"); + case "heliumEntityManagerProgram": + return new PublicKey("hemjuPXBpNvggtaUnN1MwT3wrdhttKEfosTcc2P9Pg8"); default: return; } diff --git a/packages/helium-entity-manager-sdk/src/pdas.ts b/packages/helium-entity-manager-sdk/src/pdas.ts index 2d3fb0b72..d3e4dc489 100644 --- a/packages/helium-entity-manager-sdk/src/pdas.ts +++ b/packages/helium-entity-manager-sdk/src/pdas.ts @@ -50,6 +50,18 @@ export const dataOnlyEscrowKey = (dataOnly: PublicKey, programId: PublicKey = PR programId, ); +export const sharedMerkleKey = ( + proofSize: number, + programId: PublicKey = PROGRAM_ID +) => { + const proofSizeBuffer = Buffer.alloc(1); + proofSizeBuffer.writeUint8(proofSize); + return PublicKey.findProgramAddressSync( + [Buffer.from("shared_merkle", "utf-8"), proofSizeBuffer], + programId + ); +}; + export const makerKey = (dao: PublicKey, name: String, programId: PublicKey = PROGRAM_ID) => PublicKey.findProgramAddressSync( [Buffer.from("maker", "utf-8"), dao.toBuffer(), Buffer.from(name, "utf-8")], diff --git a/packages/helium-entity-manager-sdk/src/resolvers.ts b/packages/helium-entity-manager-sdk/src/resolvers.ts index 4456f4205..1fdbded8c 100644 --- a/packages/helium-entity-manager-sdk/src/resolvers.ts +++ b/packages/helium-entity-manager-sdk/src/resolvers.ts @@ -10,7 +10,7 @@ import { } from "@solana/spl-token"; import { PublicKey } from "@solana/web3.js"; import { init } from "./init"; -import { iotInfoKey, keyToAssetKey, mobileInfoKey, programApprovalKey } from "./pdas"; +import { iotInfoKey, keyToAssetKey, mobileInfoKey, programApprovalKey, sharedMerkleKey } from "./pdas"; import { notEmittedKey } from "@helium/no-emit-sdk"; export const heliumEntityManagerResolvers = combineResolvers( @@ -151,6 +151,14 @@ export const heliumEntityManagerResolvers = combineResolvers( ); } }), + resolveIndividual(async ({ path, args }) => { + if ( + path[path.length - 1] === "sharedMerkle" && + args[0].proofSize + ) { + return sharedMerkleKey(args[0].proofSize)[0]; + } + }), ataResolver({ instruction: "issueIotOperationsFundV0", account: "recipientAccount", diff --git a/packages/helium-vote-service/.env b/packages/helium-vote-service/.env new file mode 100644 index 000000000..4d4fecb52 --- /dev/null +++ b/packages/helium-vote-service/.env @@ -0,0 +1,4 @@ +PGDATABASE=postgres +PGUSER=postgres +PGPASSWORD=postgres +SOLANA_URL=https://solana-rpc.web.test-helium.com?session-key=Pluto diff --git a/packages/iot-routing-manager-sdk/package.json b/packages/iot-routing-manager-sdk/package.json new file mode 100644 index 000000000..e9a0988b0 --- /dev/null +++ b/packages/iot-routing-manager-sdk/package.json @@ -0,0 +1,47 @@ +{ + "name": "@helium/iot-routing-manager-sdk", + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, + "license": "Apache-2.0", + "version": "0.8.7", + "description": "Interface to the iot-routing-manager smart contract", + "repository": { + "type": "git", + "url": "https://github.com/helium/helium-program-libary" + }, + "main": "./lib/cjs/index.js", + "module": "./lib/esm/src/index.js", + "types": "./lib/types/src/index.d.ts", + "sideEffects": false, + "files": [ + "lib" + ], + "exports": { + "import": "./lib/esm/src/index.js", + "require": "./lib/cjs/index.js", + "types": "./lib/types/src/index.d.ts" + }, + "scripts": { + "format": "prettier --write \"src/**/*.{ts,tsx}\"", + "precommit": "npx git-format-staged -f 'prettier --ignore-unknown --stdin --stdin-filepath \"{}\"' .", + "clean": "npx shx mkdir -p lib && npx shx rm -rf lib", + "package": "npx shx mkdir -p lib/cjs lib/esm", + "prebuild": "npm run clean && npm run package" + }, + "dependencies": { + "@coral-xyz/anchor": "^0.28.0", + "@helium/anchor-resolvers": "^0.8.7", + "@helium/helium-entity-manager-sdk": "^0.8.7", + "bn.js": "^5.2.0", + "bs58": "^4.0.1" + }, + "devDependencies": { + "git-format-staged": "^2.1.3", + "ts-loader": "^9.2.3", + "ts-node": "^10.9.1", + "typescript": "^5.2.2" + }, + "gitHead": "5a8bf0b7b88e5934ef8d774e686f7c95804fbb8d" +} diff --git a/packages/iot-routing-manager-sdk/src/constants.ts b/packages/iot-routing-manager-sdk/src/constants.ts new file mode 100644 index 000000000..e415c014f --- /dev/null +++ b/packages/iot-routing-manager-sdk/src/constants.ts @@ -0,0 +1,5 @@ +import { PublicKey } from "@solana/web3.js"; + +export const PROGRAM_ID = new PublicKey( + "irtjLnjCMmyowq2m3KWqpuFB3M9gdNA9A4t4d6VWmzB" +); diff --git a/packages/iot-routing-manager-sdk/src/index.ts b/packages/iot-routing-manager-sdk/src/index.ts new file mode 100644 index 000000000..50f94038d --- /dev/null +++ b/packages/iot-routing-manager-sdk/src/index.ts @@ -0,0 +1,29 @@ +import { IotRoutingManager } from "@helium/idls/lib/types/iot_routing_manager"; +import { AnchorProvider, Idl, Program } from "@coral-xyz/anchor"; +import { PublicKey } from "@solana/web3.js"; +import { PROGRAM_ID } from "./constants"; +import { lazyDistributorResolvers } from "./resolvers"; + +export * from "./constants"; +export * from "./pdas"; +export * from "./resolvers"; + +export async function init( + provider: AnchorProvider, + programId: PublicKey = PROGRAM_ID, + idl?: Idl | null, +): Promise> { + if (!idl) { + idl = await Program.fetchIdl(programId, provider); + } + const iotRoutingManager = new Program( + idl as IotRoutingManager, + programId, + provider, + undefined, + () => { + return lazyDistributorResolvers; + } + ) as Program; + return iotRoutingManager; +} diff --git a/packages/iot-routing-manager-sdk/src/pdas.ts b/packages/iot-routing-manager-sdk/src/pdas.ts new file mode 100644 index 000000000..f736097e1 --- /dev/null +++ b/packages/iot-routing-manager-sdk/src/pdas.ts @@ -0,0 +1,72 @@ +import { PublicKey } from "@solana/web3.js"; +import { PROGRAM_ID } from "./constants"; +import BN from "bn.js"; + + +export function routingManagerKey( + subDao: PublicKey, + programId: PublicKey = PROGRAM_ID +): [PublicKey, number] { + return PublicKey.findProgramAddressSync( + [Buffer.from("routing_manager", "utf-8"), subDao.toBuffer()], + programId + ); +} + +export function organizationKey( + routingManager: PublicKey, + oui: BN, + programId: PublicKey = PROGRAM_ID +): [PublicKey, number] { + const ouiBuffer = Buffer.alloc(8) + ouiBuffer.writeBigUint64LE(BigInt(oui.toString())) + return PublicKey.findProgramAddressSync( + [Buffer.from("organization", "utf-8"), routingManager.toBuffer(), ouiBuffer], + programId + ); +} + +export function devaddrConstraintKey( + organization: PublicKey, + startAddr: BN, + programId: PublicKey = PROGRAM_ID +): [PublicKey, number] { + const startAddrBuffer = Buffer.alloc(8); + startAddrBuffer.writeBigUint64LE(BigInt(startAddr.toString())); + return PublicKey.findProgramAddressSync( + [ + Buffer.from("devaddr_constraint", "utf-8"), + organization.toBuffer(), + startAddrBuffer, + ], + programId + ); +} + +export function netIdKey( + routingManager: PublicKey, + id: BN, + programId: PublicKey = PROGRAM_ID +): [PublicKey, number] { + const idBuffer = Buffer.alloc(8); + idBuffer.writeBigUint64LE(BigInt(id.toString())); + return PublicKey.findProgramAddressSync( + [ + Buffer.from("net_id", "utf-8"), + routingManager.toBuffer(), + idBuffer, + ], + programId + ); +} + +export function organizationDelegateKey( + organization: PublicKey, + delegate: PublicKey, + programId: PublicKey = PROGRAM_ID +): [PublicKey, number] { + return PublicKey.findProgramAddressSync( + [Buffer.from("organization_delegate", "utf-8"), organization.toBuffer(), delegate.toBuffer()], + programId + ); +} diff --git a/packages/iot-routing-manager-sdk/src/resolvers.ts b/packages/iot-routing-manager-sdk/src/resolvers.ts new file mode 100644 index 000000000..30c623662 --- /dev/null +++ b/packages/iot-routing-manager-sdk/src/resolvers.ts @@ -0,0 +1,86 @@ +import { Accounts, BorshAccountsCoder, Program, Provider } from "@coral-xyz/anchor"; +import { heliumCommonResolver } from "@helium/anchor-resolvers"; +import { + ataResolver, + combineResolvers, + resolveIndividual, +} from "@helium/anchor-resolvers"; +import { PublicKey } from "@solana/web3.js"; +import { devaddrConstraintKey, netIdKey, organizationKey } from "./pdas"; +import { PROGRAM_ID } from "./constants"; +import { heliumEntityManagerResolvers, keyToAssetKey, programApprovalKey, sharedMerkleKey } from "@helium/helium-entity-manager-sdk"; +import { IDL } from "@helium/idls/lib/types/iot_routing_manager"; + +export const lazyDistributorResolvers = combineResolvers( + heliumCommonResolver, + heliumEntityManagerResolvers, + ataResolver({ + instruction: "initializeRoutingManagerV0", + account: "tokenAccount", + mint: "collection", + owner: "routingManager", + }), + ataResolver({ + account: "payerIotAccount", + mint: "iotMint", + owner: "payer", + }), + resolveIndividual(async ({ args, path, accounts, provider }) => { + if ( + args[0] && + args[0].netId && + path[path.length - 1] == "netId" && + accounts.routingManager + ) { + return netIdKey(accounts.routingManager as PublicKey, args[0].netId)[0]; + } else if ( + args[0] && + args[0].oui && + path[path.length - 1] === "organization" && + accounts.routingManager + ) { + return organizationKey( + accounts.routingManager as PublicKey, + args[0].oui + )[0]; + } else if ( + path[path.length - 1] === "devaddrConstraint" && + accounts.organization && + accounts.netId + ) { + return devaddrConstraintKey( + accounts.organization as PublicKey, + (args[0] && args[0].startAddr) ?? + (await getNetId(provider, accounts.netId as PublicKey)) + .currentAddrOffset + )[0]; + } else if (path[path.length - 1] == "programApproval" && accounts.dao) { + return programApprovalKey(accounts.dao as PublicKey, PROGRAM_ID)[0]; + } else if ( + path[path.length - 1] === "keyToAsset" && + args[args.length - 1] && + args[args.length - 1].oui && + accounts.dao + ) { + return ( + await keyToAssetKey( + accounts.dao as PublicKey, + `OUI_${args[args.length - 1].oui}`, + "utf-8" + ) + )[0]; + } else if (path[path.length - 1] === "sharedMerkle") { + return sharedMerkleKey(3)[0]; + } + }) +); + +async function getNetId(provider: Provider, netId: PublicKey) { + const idl = await Program.fetchIdl(PROGRAM_ID, provider); + const netIdAccount = await provider.connection.getAccountInfo(netId); + if (!netIdAccount) { + throw new Error("NetId account not found"); + } + const coder = new BorshAccountsCoder(idl!) + return coder.decode("NetIdV0", netIdAccount.data) +} diff --git a/packages/iot-routing-manager-sdk/tsconfig.cjs.json b/packages/iot-routing-manager-sdk/tsconfig.cjs.json new file mode 100644 index 000000000..950b2365f --- /dev/null +++ b/packages/iot-routing-manager-sdk/tsconfig.cjs.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.cjs.json", + "include": ["src"], + "compilerOptions": { + "outDir": "lib/cjs" + } +} \ No newline at end of file diff --git a/packages/iot-routing-manager-sdk/tsconfig.esm.json b/packages/iot-routing-manager-sdk/tsconfig.esm.json new file mode 100644 index 000000000..f2835b2e5 --- /dev/null +++ b/packages/iot-routing-manager-sdk/tsconfig.esm.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.esm.json", + "include": ["src"], + "compilerOptions": { + "outDir": "lib/esm", + "declarationDir": "lib/types" + } +} \ No newline at end of file diff --git a/packages/iot-routing-manager-sdk/tsconfig.json b/packages/iot-routing-manager-sdk/tsconfig.json new file mode 100644 index 000000000..cd351dee2 --- /dev/null +++ b/packages/iot-routing-manager-sdk/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../../tsconfig.root.json", + "references": [ + { + "path": "../idls" + }, + { + "path": "../anchor-resolvers" + }, + { + "path": "../helium-entity-manager-sdk" + }, + { + "path": "../circuit-breaker-sdk" + }, + { + "path": "./tsconfig.cjs.json" + }, + { + "path": "./tsconfig.esm.json" + } + ] +} diff --git a/packages/iot-routing-manager-sdk/yarn.deploy.lock b/packages/iot-routing-manager-sdk/yarn.deploy.lock new file mode 100644 index 000000000..aaeaef403 --- /dev/null +++ b/packages/iot-routing-manager-sdk/yarn.deploy.lock @@ -0,0 +1,2433 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 6 + cacheKey: 8 + +"@babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.22.6": + version: 7.22.11 + resolution: "@babel/runtime@npm:7.22.11" + dependencies: + regenerator-runtime: "npm:^0.14.0" + checksum: a5cd6683a8fcdb8065cb1677f221e22f6c67ec8f15ad1d273b180b93ab3bd86c66da2c48f500d4e72d8d2cfa85ff4872a3f350e5aa3855630036af5da765c001 + languageName: node + linkType: hard + +"@babel/runtime@npm:^7.23.4": + version: 7.24.1 + resolution: "@babel/runtime@npm:7.24.1" + dependencies: + regenerator-runtime: ^0.14.0 + checksum: 5c8f3b912ba949865f03b3cf8395c60e1f4ebd1033fbd835bdfe81b6cac8a87d85bc3c7aded5fcdf07be044c9ab8c818f467abe0deca50020c72496782639572 + languageName: node + linkType: hard + +"@coral-xyz/anchor@npm:^0.28.0": + version: 0.28.0 + resolution: "@coral-xyz/anchor@npm:0.28.0" + dependencies: + "@coral-xyz/borsh": "npm:^0.28.0" + "@solana/web3.js": "npm:^1.68.0" + base64-js: "npm:^1.5.1" + bn.js: "npm:^5.1.2" + bs58: "npm:^4.0.1" + buffer-layout: "npm:^1.2.2" + camelcase: "npm:^6.3.0" + cross-fetch: "npm:^3.1.5" + crypto-hash: "npm:^1.3.0" + eventemitter3: "npm:^4.0.7" + js-sha256: "npm:^0.9.0" + pako: "npm:^2.0.3" + snake-case: "npm:^3.0.4" + superstruct: "npm:^0.15.4" + toml: "npm:^3.0.0" + checksum: 58b3677b5b2ce2c779045184ce4a0ef696966a6a58f41c1c56f6f178db0491acecb6ec677ce0502f0b382a2c724f9c2860d82cc88601784d556d95fbeda415e5 + languageName: node + linkType: hard + +"@coral-xyz/borsh@npm:^0.28.0": + version: 0.28.0 + resolution: "@coral-xyz/borsh@npm:0.28.0" + dependencies: + bn.js: "npm:^5.1.2" + buffer-layout: "npm:^1.2.0" + peerDependencies: + "@solana/web3.js": ^1.68.0 + checksum: bc2b06b777f9ed43d3b886d2350826bd44d5b932c4fd4471af5956e8755236f5854938c890ee4986d88f61d1439e1d84e715c43dcb6dca4e76198c1ce8dc7a58 + languageName: node + linkType: hard + +"@cspotcode/source-map-support@npm:^0.8.0": + version: 0.8.1 + resolution: "@cspotcode/source-map-support@npm:0.8.1" + dependencies: + "@jridgewell/trace-mapping": "npm:0.3.9" + checksum: 5718f267085ed8edb3e7ef210137241775e607ee18b77d95aa5bd7514f47f5019aa2d82d96b3bf342ef7aa890a346fa1044532ff7cc3009e7d24fce3ce6200fa + languageName: node + linkType: hard + +"@helium/account-fetch-cache@^0.8.7": + version: 0.0.0-use.local + resolution: "@helium/account-fetch-cache@workspace:packages/account-fetch-cache" + dependencies: + "@solana/web3.js": ^1.78.8 + git-format-staged: ^2.1.3 + ts-loader: ^9.2.3 + typescript: ^5.2.2 + languageName: unknown + linkType: soft + +"@helium/address@npm:^4.10.2": + version: 4.10.2 + resolution: "@helium/address@npm:4.10.2" + dependencies: + bs58: "npm:^5.0.0" + js-sha256: "npm:^0.9.0" + multiformats: "npm:^9.6.4" + checksum: 4d83df57c638ed1496a92241a2f45da671e11b6397f02ab65c5281cbd1a435548e7ffd5be969d8d214b5af045e9be4bdd2d89f41744289c17e6410d458b03bcc + languageName: node + linkType: hard + +"@helium/anchor-resolvers@^0.8.7": + 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.78.8 + git-format-staged: ^2.1.3 + ts-loader: ^9.2.3 + typescript: ^5.2.2 + peerDependencies: + "@coral-xyz/anchor": ^0.28.0 + languageName: unknown + linkType: soft + +"@helium/anchor-resolvers@npm:^0.5.0": + version: 0.5.0 + resolution: "@helium/anchor-resolvers@npm:0.5.0" + dependencies: + "@solana/spl-token": ^0.3.8 + "@solana/web3.js": ^1.78.4 + peerDependencies: + "@coral-xyz/anchor": ^0.28.0 + checksum: b20f52072bb8e1cb097e951c98a66149989035a58d3f4de1998c3043a1e04e36b6dee2e0760b99d0fbd5fa4e47f499972ad17f6560e1f3c7424e96a1e35343a9 + languageName: node + linkType: hard + +"@helium/circuit-breaker-sdk@^0.8.7": + version: 0.0.0-use.local + resolution: "@helium/circuit-breaker-sdk@workspace:packages/circuit-breaker-sdk" + dependencies: + "@coral-xyz/anchor": ^0.28.0 + "@helium/anchor-resolvers": ^0.8.7 + "@helium/idls": ^0.8.7 + 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/helium-entity-manager-sdk@^0.8.7": + version: 0.0.0-use.local + resolution: "@helium/helium-entity-manager-sdk@workspace:packages/helium-entity-manager-sdk" + dependencies: + "@coral-xyz/anchor": ^0.28.0 + "@helium/address": ^4.10.2 + "@helium/anchor-resolvers": ^0.8.7 + "@helium/helium-sub-daos-sdk": ^0.8.7 + "@helium/idls": ^0.8.7 + "@helium/no-emit-sdk": ^0.8.7 + "@helium/spl-utils": ^0.8.7 + "@types/crypto-js": ^4.1.1 + bn.js: ^5.2.0 + bs58: ^4.0.1 + crypto-js: ^4.1.1 + git-format-staged: ^2.1.3 + js-sha256: ^0.9.0 + ts-loader: ^9.2.3 + ts-node: ^10.9.1 + typescript: ^5.2.2 + languageName: unknown + linkType: soft + +"@helium/helium-sub-daos-sdk@^0.8.7": + version: 0.0.0-use.local + resolution: "@helium/helium-sub-daos-sdk@workspace:packages/helium-sub-daos-sdk" + dependencies: + "@coral-xyz/anchor": ^0.28.0 + "@helium/anchor-resolvers": ^0.8.7 + "@helium/circuit-breaker-sdk": ^0.8.7 + "@helium/treasury-management-sdk": ^0.8.7 + "@helium/voter-stake-registry-sdk": ^0.8.7 + 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/idls@^0.8.7": + version: 0.0.0-use.local + resolution: "@helium/idls@workspace:packages/idls" + dependencies: + "@coral-xyz/anchor": ^0.28.0 + "@solana/web3.js": ^1.78.8 + bn.js: ^5.2.0 + borsh: ^0.7.0 + bs58: ^4.0.1 + ts-loader: ^9.2.3 + typescript: ^5.2.2 + languageName: unknown + linkType: soft + +"@helium/idls@npm:^0.5.0": + version: 0.5.0 + resolution: "@helium/idls@npm:0.5.0" + dependencies: + "@coral-xyz/anchor": ^0.28.0 + "@solana/web3.js": ^1.78.4 + bn.js: ^5.2.0 + borsh: ^0.7.0 + bs58: ^4.0.1 + checksum: 66a021a9953cf0a96f0eaf8932a2006286c266cc323f171eedf2bc18a94d55ad035cc7da9e21c99dc70fc77b1681630382a55999a2f40228f33611d7621a0c7c + languageName: node + linkType: hard + +"@helium/iot-routing-manager-sdk@workspace:.": + version: 0.0.0-use.local + resolution: "@helium/iot-routing-manager-sdk@workspace:." + dependencies: + "@coral-xyz/anchor": ^0.28.0 + "@helium/anchor-resolvers": ^0.8.7 + "@helium/helium-entity-manager-sdk": ^0.8.7 + 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/no-emit-sdk@^0.8.7": + version: 0.0.0-use.local + resolution: "@helium/no-emit-sdk@workspace:packages/no-emit-sdk" + dependencies: + "@coral-xyz/anchor": ^0.28.0 + "@helium/anchor-resolvers": ^0.5.0 + "@helium/idls": ^0.5.0 + 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/spl-utils@^0.8.7": + version: 0.0.0-use.local + resolution: "@helium/spl-utils@workspace:packages/spl-utils" + dependencies: + "@coral-xyz/anchor": ^0.28.0 + "@helium/account-fetch-cache": ^0.8.7 + "@helium/address": ^4.10.2 + "@helium/anchor-resolvers": ^0.8.7 + "@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.78.8 + axios: ^1.5.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 + +"@helium/treasury-management-sdk@^0.8.7": + version: 0.0.0-use.local + resolution: "@helium/treasury-management-sdk@workspace:packages/treasury-management-sdk" + dependencies: + "@coral-xyz/anchor": ^0.28.0 + "@helium/anchor-resolvers": ^0.8.7 + "@helium/circuit-breaker-sdk": ^0.8.7 + "@helium/idls": ^0.8.7 + 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/voter-stake-registry-sdk@^0.8.7": + version: 0.0.0-use.local + resolution: "@helium/voter-stake-registry-sdk@workspace:packages/voter-stake-registry-sdk" + dependencies: + "@coral-xyz/anchor": ^0.28.0 + "@helium/anchor-resolvers": ^0.8.7 + "@helium/idls": ^0.8.7 + "@metaplex-foundation/mpl-token-metadata": ^2.10.0 + "@solana/spl-token": ^0.3.8 + 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 + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 4a473b9b32a7d4d3cfb7a614226e555091ff0c5a29a1734c28c72a182c2f6699b26fc6b5c2131dfd841e86b185aea714c72201d7c98c2fba5f17709333a67aeb + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.0.3": + version: 3.1.1 + resolution: "@jridgewell/resolve-uri@npm:3.1.1" + checksum: f5b441fe7900eab4f9155b3b93f9800a916257f4e8563afbcd3b5a5337b55e52bd8ae6735453b1b745457d9f6cdb16d74cd6220bbdd98cf153239e13f6cbb653 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.10": + version: 1.4.15 + resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" + checksum: b881c7e503db3fc7f3c1f35a1dd2655a188cc51a3612d76efc8a6eb74728bef5606e6758ee77423e564092b4a518aba569bbb21c9bac5ab7a35b0c6ae7e344c8 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:0.3.9": + version: 0.3.9 + resolution: "@jridgewell/trace-mapping@npm:0.3.9" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.0.3" + "@jridgewell/sourcemap-codec": "npm:^1.4.10" + checksum: d89597752fd88d3f3480845691a05a44bd21faac18e2185b6f436c3b0fd0c5a859fbbd9aaa92050c4052caf325ad3e10e2e1d1b64327517471b7d51babc0ddef + 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" + dependencies: + "@noble/hashes": "npm:1.3.2" + checksum: bb798d7a66d8e43789e93bc3c2ddff91a1e19fdb79a99b86cd98f1e5eff0ee2024a2672902c2576ef3577b6f282f3b5c778bebd55761ddbb30e36bf275e83dd0 + languageName: node + linkType: hard + +"@noble/curves@npm:^1.2.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/hashes@npm:1.3.2, @noble/hashes@npm:^1.3.1": + version: 1.3.2 + resolution: "@noble/hashes@npm:1.3.2" + checksum: fe23536b436539d13f90e4b9be843cc63b1b17666a07634a2b1259dded6f490be3d050249e6af98076ea8f2ea0d56f578773c2197f2aa0eeaa5fba5bc18ba474 + languageName: node + linkType: hard + +"@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.3.3": + 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" + dependencies: + semver: "npm:^7.3.5" + checksum: a50a6818de5fc557d0b0e6f50ec780a7a02ab8ad07e5ac8b16bf519e0ad60a144ac64f97d05c443c3367235d337182e1d012bbac0eb8dbae8dc7b40b193efd0e + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f + 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" + dependencies: + "@solana/buffer-layout": "npm:^4.0.0" + "@solana/web3.js": "npm:^1.32.0" + bigint-buffer: "npm:^1.1.5" + bignumber.js: "npm:^9.0.1" + checksum: 9284242245b18b49577195ba7548263850be865a4a2d183944fa01bb76382039db589aab8473698e9bb734b515ada9b4d70db0a72e341c5d567c59b83d6d0840 + languageName: node + linkType: hard + +"@solana/buffer-layout@npm:^4.0.0, @solana/buffer-layout@npm:^4.0.1": + version: 4.0.1 + resolution: "@solana/buffer-layout@npm:4.0.1" + dependencies: + buffer: "npm:~6.0.3" + checksum: bf846888e813187243d4008a7a9f58b49d16cbd995b9d7f1b72898aa510ed77b1ce5e8468e7b2fd26dd81e557a4e74a666e21fccb95f123c1f740d41138bbacd + languageName: node + linkType: hard + +"@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: + "@solana/buffer-layout": "npm:^4.0.0" + "@solana/buffer-layout-utils": "npm:^0.2.0" + buffer: "npm:^6.0.3" + peerDependencies: + "@solana/web3.js": ^1.47.4 + checksum: 01f4f87112b0ad277701a3bcb8e03069b69449b92724b17959107686731082bfd3475b5f105e1e8f04badd2e810a43d5ef811744ced5178eea1232de8fd75147 + languageName: node + linkType: hard + +"@solana/web3.js@npm:^1.32.0, @solana/web3.js@npm:^1.56.2, @solana/web3.js@npm:^1.66.2, @solana/web3.js@npm:^1.68.0, @solana/web3.js@npm:^1.78.4": + version: 1.78.4 + resolution: "@solana/web3.js@npm:1.78.4" + dependencies: + "@babel/runtime": "npm:^7.22.6" + "@noble/curves": "npm:^1.0.0" + "@noble/hashes": "npm:^1.3.1" + "@solana/buffer-layout": "npm:^4.0.0" + agentkeepalive: "npm:^4.3.0" + bigint-buffer: "npm:^1.1.5" + bn.js: "npm:^5.2.1" + borsh: "npm:^0.7.0" + bs58: "npm:^4.0.1" + buffer: "npm:6.0.3" + fast-stable-stringify: "npm:^1.0.0" + jayson: "npm:^4.1.0" + node-fetch: "npm:^2.6.12" + rpc-websockets: "npm:^7.5.1" + superstruct: "npm:^0.14.2" + checksum: e1c44c6cbec87cdfd4d6d23b4241b746e14ed3a9ca73d596693758d91ac825cecf579345da3b0b7bb5e54b6794791bc0eac02cadf11f1ec79e859b6536f26f11 + languageName: node + linkType: hard + +"@solana/web3.js@npm:^1.78.8": + version: 1.91.3 + resolution: "@solana/web3.js@npm:1.91.3" + dependencies: + "@babel/runtime": ^7.23.4 + "@noble/curves": ^1.2.0 + "@noble/hashes": ^1.3.3 + "@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: ^7.5.1 + superstruct: ^0.14.2 + checksum: 5b251915057368d0615d6a6f0de7b4d4129c3d0643599551c0a342125601418634851b633a47d19da481973406f0f2928fa4bf1a2c57fb19914e69fd5b81c302 + languageName: node + linkType: hard + +"@tootallnate/once@npm:2": + version: 2.0.0 + resolution: "@tootallnate/once@npm:2.0.0" + checksum: ad87447820dd3f24825d2d947ebc03072b20a42bfc96cbafec16bff8bbda6c1a81fcb0be56d5b21968560c5359a0af4038a68ba150c3e1694fe4c109a063bed8 + languageName: node + linkType: hard + +"@tsconfig/node10@npm:^1.0.7": + version: 1.0.9 + resolution: "@tsconfig/node10@npm:1.0.9" + checksum: a33ae4dc2a621c0678ac8ac4bceb8e512ae75dac65417a2ad9b022d9b5411e863c4c198b6ba9ef659e14b9fb609bbec680841a2e84c1172df7a5ffcf076539df + languageName: node + linkType: hard + +"@tsconfig/node12@npm:^1.0.7": + version: 1.0.11 + resolution: "@tsconfig/node12@npm:1.0.11" + checksum: 5ce29a41b13e7897a58b8e2df11269c5395999e588b9a467386f99d1d26f6c77d1af2719e407621412520ea30517d718d5192a32403b8dfcc163bf33e40a338a + languageName: node + linkType: hard + +"@tsconfig/node14@npm:^1.0.0": + version: 1.0.3 + resolution: "@tsconfig/node14@npm:1.0.3" + checksum: 19275fe80c4c8d0ad0abed6a96dbf00642e88b220b090418609c4376e1cef81bf16237bf170ad1b341452feddb8115d8dd2e5acdfdea1b27422071163dc9ba9d + languageName: node + linkType: hard + +"@tsconfig/node16@npm:^1.0.2": + version: 1.0.4 + resolution: "@tsconfig/node16@npm:1.0.4" + checksum: 202319785901f942a6e1e476b872d421baec20cf09f4b266a1854060efbf78cde16a4d256e8bc949d31e6cd9a90f1e8ef8fb06af96a65e98338a2b6b0de0a0ff + languageName: node + linkType: hard + +"@types/connect@npm:^3.4.33": + version: 3.4.35 + resolution: "@types/connect@npm:3.4.35" + dependencies: + "@types/node": "npm:*" + checksum: fe81351470f2d3165e8b12ce33542eef89ea893e36dd62e8f7d72566dfb7e448376ae962f9f3ea888547ce8b55a40020ca0e01d637fab5d99567673084542641 + languageName: node + linkType: hard + +"@types/crypto-js@npm:^4.1.1": + version: 4.1.1 + resolution: "@types/crypto-js@npm:4.1.1" + checksum: ea3d6a67b69f88baeb6af96004395903d2367a41bd5cd86306da23a44dd96589749495da50974a9b01bb5163c500764c8a33706831eade036bddae016417e3ea + languageName: node + linkType: hard + +"@types/node@npm:*": + version: 20.5.7 + resolution: "@types/node@npm:20.5.7" + checksum: fc284c8e16ddc04569730d58e87eae349eb1c3dd9020cb79a1862d9d9add6f04e7367a236f3252db8db2572f90278e250f4cd43d27d264972b54394eaba1ed76 + languageName: node + linkType: hard + +"@types/node@npm:^12.12.54": + version: 12.20.55 + resolution: "@types/node@npm:12.20.55" + checksum: e4f86785f4092706e0d3b0edff8dca5a13b45627e4b36700acd8dfe6ad53db71928c8dee914d4276c7fd3b6ccd829aa919811c9eb708a2c8e4c6eb3701178c37 + languageName: node + linkType: hard + +"@types/ws@npm:^7.4.4": + version: 7.4.7 + resolution: "@types/ws@npm:7.4.7" + dependencies: + "@types/node": "npm:*" + checksum: b4c9b8ad209620c9b21e78314ce4ff07515c0cadab9af101c1651e7bfb992d7fd933bd8b9c99d110738fd6db523ed15f82f29f50b45510288da72e964dedb1a3 + languageName: node + linkType: hard + +"JSONStream@npm:^1.3.5": + version: 1.3.5 + resolution: "JSONStream@npm:1.3.5" + dependencies: + jsonparse: "npm:^1.2.0" + through: "npm:>=2.2.7 <3" + bin: + JSONStream: ./bin.js + checksum: 2605fa124260c61bad38bb65eba30d2f72216a78e94d0ab19b11b4e0327d572b8d530c0c9cc3b0764f727ad26d39e00bf7ebad57781ca6368394d73169c59e46 + languageName: node + linkType: hard + +"abbrev@npm:^1.0.0": + version: 1.1.1 + resolution: "abbrev@npm:1.1.1" + checksum: a4a97ec07d7ea112c517036882b2ac22f3109b7b19077dc656316d07d308438aac28e4d9746dc4d84bf6b1e75b4a7b0a5f3cb30592419f128ca9a8cee3bcfa17 + languageName: node + linkType: hard + +"acorn-walk@npm:^8.1.1": + version: 8.2.0 + resolution: "acorn-walk@npm:8.2.0" + checksum: 1715e76c01dd7b2d4ca472f9c58968516a4899378a63ad5b6c2d668bba8da21a71976c14ec5f5b75f887b6317c4ae0b897ab141c831d741dc76024d8745f1ad1 + languageName: node + linkType: hard + +"acorn@npm:^8.4.1": + version: 8.10.0 + resolution: "acorn@npm:8.10.0" + bin: + acorn: bin/acorn + checksum: 538ba38af0cc9e5ef983aee196c4b8b4d87c0c94532334fa7e065b2c8a1f85863467bb774231aae91613fcda5e68740c15d97b1967ae3394d20faddddd8af61d + languageName: node + linkType: hard + +"agent-base@npm:6, agent-base@npm:^6.0.2": + version: 6.0.2 + resolution: "agent-base@npm:6.0.2" + dependencies: + debug: "npm:4" + checksum: f52b6872cc96fd5f622071b71ef200e01c7c4c454ee68bc9accca90c98cfb39f2810e3e9aa330435835eedc8c23f4f8a15267f67c6e245d2b33757575bdac49d + languageName: node + linkType: hard + +"agentkeepalive@npm:^4.2.1, agentkeepalive@npm:^4.3.0, agentkeepalive@npm:^4.5.0": + version: 4.5.0 + resolution: "agentkeepalive@npm:4.5.0" + dependencies: + humanize-ms: "npm:^1.2.1" + checksum: 13278cd5b125e51eddd5079f04d6fe0914ac1b8b91c1f3db2c1822f99ac1a7457869068997784342fe455d59daaff22e14fb7b8c3da4e741896e7e31faf92481 + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.0.1 + resolution: "ansi-regex@npm:6.0.1" + checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: 513b44c3b2105dd14cc42a19271e80f386466c4be574bccf60b627432f9198571ebf4ab1e4c3ba17347658f4ee1711c163d574248c0c1cdc2d5917a0ad582ec4 + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9 + 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" + checksum: 5615cadcfb45289eea63f8afd064ab656006361020e1735112e346593856f87435e02d8dcc7ff0d11928bc7d425f27bc7c2a84f6c0b35ab0ff659c814c138a24 + languageName: node + linkType: hard + +"are-we-there-yet@npm:^3.0.0": + version: 3.0.1 + resolution: "are-we-there-yet@npm:3.0.1" + dependencies: + delegates: "npm:^1.0.0" + readable-stream: "npm:^3.6.0" + checksum: 52590c24860fa7173bedeb69a4c05fb573473e860197f618b9a28432ee4379049336727ae3a1f9c4cb083114601c1140cee578376164d0e651217a9843f9fe83 + languageName: node + linkType: hard + +"arg@npm:^4.1.0": + version: 4.1.3 + resolution: "arg@npm:4.1.3" + checksum: 544af8dd3f60546d3e4aff084d451b96961d2267d668670199692f8d054f0415d86fc5497d0e641e91546f0aa920e7c29e5250e99fc89f5552a34b5d93b77f43 + 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.5.0": + version: 1.5.0 + resolution: "axios@npm:1.5.0" + dependencies: + follow-redirects: "npm:^1.15.0" + form-data: "npm:^4.0.0" + proxy-from-env: "npm:^1.1.0" + checksum: e7405a5dbbea97760d0e6cd58fecba311b0401ddb4a8efbc4108f5537da9b3f278bde566deb777935a960beec4fa18e7b8353881f2f465e4f2c0e949fead35be + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + languageName: node + linkType: hard + +"base-x@npm:^3.0.2": + version: 3.0.9 + resolution: "base-x@npm:3.0.9" + dependencies: + safe-buffer: "npm:^5.0.1" + checksum: 957101d6fd09e1903e846fd8f69fd7e5e3e50254383e61ab667c725866bec54e5ece5ba49ce385128ae48f9ec93a26567d1d5ebb91f4d56ef4a9cc0d5a5481e8 + 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, base64-js@npm:^1.5.1": + version: 1.5.1 + resolution: "base64-js@npm:1.5.1" + checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 + languageName: node + linkType: hard + +"bigint-buffer@npm:^1.1.5": + version: 1.1.5 + resolution: "bigint-buffer@npm:1.1.5" + dependencies: + bindings: "npm:^1.3.0" + node-gyp: "npm:latest" + checksum: d010c9f57758bcdaccb435d88b483ffcc95fe8bbc6e7fb3a44fb5221f29c894ffaf4a3c5a4a530e0e7d6608203c2cde9b79ee4f2386cd6d4462d1070bc8c9f4e + languageName: node + linkType: hard + +"bignumber.js@npm:^9.0.1": + version: 9.1.2 + resolution: "bignumber.js@npm:9.1.2" + checksum: 582c03af77ec9cb0ebd682a373ee6c66475db94a4325f92299621d544aa4bd45cb45fd60001610e94aef8ae98a0905fa538241d9638d4422d57abbeeac6fadaf + languageName: node + linkType: hard + +"bindings@npm:^1.3.0": + version: 1.5.0 + resolution: "bindings@npm:1.5.0" + dependencies: + file-uri-to-path: "npm:1.0.0" + checksum: 65b6b48095717c2e6105a021a7da4ea435aa8d3d3cd085cb9e85bcb6e5773cf318c4745c3f7c504412855940b585bdf9b918236612a1c7a7942491de176f1ae7 + languageName: node + linkType: hard + +"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 + languageName: node + linkType: hard + +"borsh@npm:^0.7.0": + version: 0.7.0 + resolution: "borsh@npm:0.7.0" + dependencies: + bn.js: "npm:^5.2.0" + bs58: "npm:^4.0.0" + text-encoding-utf-8: "npm:^1.0.2" + checksum: e98bfb5f7cfb820819c2870b884dac58dd4b4ce6a86c286c8fbf5c9ca582e73a8c6094df67e81a28c418ff07a309c6b118b2e27fdfea83fd92b8100c741da0b5 + languageName: node + linkType: hard + +"brace-expansion@npm:^1.1.7": + version: 1.1.11 + resolution: "brace-expansion@npm:1.1.11" + dependencies: + balanced-match: "npm:^1.0.0" + concat-map: "npm:0.0.1" + checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + 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" + dependencies: + base-x: "npm:^3.0.2" + checksum: b3c5365bb9e0c561e1a82f1a2d809a1a692059fae016be233a6127ad2f50a6b986467c3a50669ce4c18929dcccb297c5909314dd347a25a68c21b68eb3e95ac2 + 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" + dependencies: + base64-js: "npm:^1.3.1" + ieee754: "npm:^1.2.1" + checksum: 5ad23293d9a731e4318e420025800b42bf0d264004c0286c8cc010af7a270c7a0f6522e84f54b9ad65cbd6db20b8badbfd8d2ebf4f80fa03dab093b89e68c3f9 + languageName: node + linkType: hard + +"bufferutil@npm:^4.0.1": + version: 4.0.7 + resolution: "bufferutil@npm:4.0.7" + dependencies: + node-gyp: "npm:latest" + node-gyp-build: "npm:^4.3.0" + checksum: f75aa87e3d1b99b87a95f60a855e63f70af07b57fb8443e75a2ddfef2e47788d130fdd46e3a78fd7e0c10176082b26dfbed970c5b8632e1cc299cafa0e93ce45 + languageName: node + linkType: hard + +"cacache@npm:^17.0.0": + version: 17.1.4 + resolution: "cacache@npm:17.1.4" + dependencies: + "@npmcli/fs": "npm:^3.1.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^7.7.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^1.0.2" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^4.0.0" + ssri: "npm:^10.0.0" + tar: "npm:^6.1.11" + unique-filename: "npm:^3.0.0" + checksum: b7751df756656954a51201335addced8f63fc53266fa56392c9f5ae83c8d27debffb4458ac2d168a744a4517ec3f2163af05c20097f93d17bdc2dc8a385e14a6 + 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" + checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: 79e6bdb9fd479a205c71d89574fccfb22bd9053bd98c6c4d870d65c132e5e904e6034978e55b43d69fcaa7433af2016ee203ce76eeba9cfa554b373e7f7db336 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + +"color-support@npm:^1.1.3": + version: 1.1.3 + resolution: "color-support@npm:1.1.3" + bin: + color-support: bin.js + checksum: 9b7356817670b9a13a26ca5af1c21615463b500783b739b7634a0c2047c16cef4b2865d7576875c31c3cddf9dd621fa19285e628f20198b233a5cfdda6d0793b + 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" + checksum: ab8c07884e42c3a8dbc5dd9592c606176c7eb5c1ca5ff274bcf907039b2c41de3626f684ea75ccf4d361ba004bbaff1f577d5384c155f3871e456bdf27becf9e + languageName: node + linkType: hard + +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: 902a9f5d8967a3e2faf138d5cb784b9979bad2e6db5357c5b21c568df4ebe62bcb15108af1b2253744844eb964fc023fbd9afbbbb6ddd0bcc204c6fb5b7bf3af + languageName: node + linkType: hard + +"console-control-strings@npm:^1.1.0": + version: 1.1.0 + resolution: "console-control-strings@npm:1.1.0" + checksum: 8755d76787f94e6cf79ce4666f0c5519906d7f5b02d4b884cf41e11dcd759ed69c57da0670afd9236d229a46e0f9cf519db0cd829c6dca820bb5a5c3def584ed + languageName: node + linkType: hard + +"create-require@npm:^1.1.0": + version: 1.1.1 + resolution: "create-require@npm:1.1.1" + checksum: a9a1503d4390d8b59ad86f4607de7870b39cad43d929813599a23714831e81c520bddf61bcdd1f8e30f05fd3a2b71ae8538e946eb2786dc65c2bbc520f692eff + 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" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 + languageName: node + linkType: hard + +"crypto-hash@npm:^1.3.0": + version: 1.3.0 + resolution: "crypto-hash@npm:1.3.0" + checksum: a3a507e0d2b18fbd2da8088a1c62d0c53c009a99bbfa6d851cac069734ffa546922fa51bdd776d006459701cdda873463e5059ece3431aca048fd99e7573d138 + languageName: node + linkType: hard + +"crypto-js@npm:^4.1.1": + version: 4.1.1 + resolution: "crypto-js@npm:4.1.1" + checksum: b3747c12ee3a7632fab3b3e171ea50f78b182545f0714f6d3e7e2858385f0f4101a15f2517e033802ce9d12ba50a391575ff4638c9de3dd9b2c4bc47768d5425 + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.3.3, debug@npm:^4.3.4": + version: 4.3.4 + resolution: "debug@npm:4.3.4" + dependencies: + ms: "npm:2.1.2" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 3dbad3f94ea64f34431a9cbf0bafb61853eda57bff2880036153438f50fb5a84f27683ba0d8e5426bf41a8c6ff03879488120cf5b3a761e77953169c0600a708 + languageName: node + linkType: hard + +"delay@npm:^5.0.0": + version: 5.0.0 + resolution: "delay@npm:5.0.0" + checksum: 62f151151ecfde0d9afbb8a6be37a6d103c4cb24f35a20ef3fe56f920b0d0d0bb02bc9c0a3084d0179ef669ca332b91155f2ee4d9854622cd2cdba5fc95285f9 + 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" + checksum: a51744d9b53c164ba9c0492471a1a2ffa0b6727451bdc89e31627fdf4adda9d51277cfcbfb20f0a6f08ccb3c436f341df3e92631a3440226d93a8971724771fd + languageName: node + linkType: hard + +"diff@npm:^4.0.1": + version: 4.0.2 + resolution: "diff@npm:4.0.2" + checksum: f2c09b0ce4e6b301c221addd83bf3f454c0bc00caa3dd837cf6c127d6edf7223aa2bbe3b688feea110b7f262adbfc845b757c44c8a9f8c0c5b15d8fa9ce9d20d + languageName: node + linkType: hard + +"dot-case@npm:^3.0.4": + version: 3.0.4 + resolution: "dot-case@npm:3.0.4" + dependencies: + no-case: "npm:^3.0.4" + tslib: "npm:^2.0.3" + checksum: a65e3519414856df0228b9f645332f974f2bf5433370f544a681122eab59e66038fc3349b4be1cdc47152779dac71a5864f1ccda2f745e767c46e9c6543b1169 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 7d00d7cd8e49b9afa762a813faac332dee781932d6f2c848dc348939c4253f1d4564341b7af1d041853bc3f32c2ef141b58e0a4d9862c17a7f08f68df1e0f1ed + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: d4c5c39d5a9868b5fa152f00cada8a936868fd3367f33f71be515ecee4c803132d11b31a6222b2571b1e5f7e13890156a94880345594d0ce7e3c9895f560f192 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 8487182da74aabd810ac6d6f1994111dfc0e331b01271ae01ec1eb0ad7b5ecc2bbbbd2f053c05cb55a1ac30449527d819bbfbf0e3de1023db308cbcb47f86601 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + 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" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 8b7b1be20d2de12d2255c0bc2ca638b7af5171142693299416e6a9339bd7d88fc8d7707d913d78e0993176005405a236b066b45666b27b797252c771156ace54 + languageName: node + linkType: hard + +"es6-promise@npm:^4.0.3": + version: 4.2.8 + resolution: "es6-promise@npm:4.2.8" + checksum: 95614a88873611cb9165a85d36afa7268af5c03a378b35ca7bda9508e1d4f1f6f19a788d4bc755b3fd37c8ebba40782018e02034564ff24c9d6fa37e959ad57d + languageName: node + linkType: hard + +"es6-promisify@npm:^5.0.0": + version: 5.0.0 + resolution: "es6-promisify@npm:5.0.0" + dependencies: + es6-promise: "npm:^4.0.3" + checksum: fbed9d791598831413be84a5374eca8c24800ec71a16c1c528c43a98e2dadfb99331483d83ae6094ddb9b87e6f799a15d1553cebf756047e0865c753bc346b92 + languageName: node + linkType: hard + +"eventemitter3@npm:^4.0.7": + version: 4.0.7 + resolution: "eventemitter3@npm:4.0.7" + checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374 + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 3d21519a4f8207c99f7457287291316306255a328770d320b401114ec8481986e4e467e854cb9914dd965e0a1ca810a23ccb559c642c88f4c7f55c55778a9b48 + languageName: node + linkType: hard + +"eyes@npm:^0.1.8": + version: 0.1.8 + resolution: "eyes@npm:0.1.8" + checksum: c31703a92bf36ba75ee8d379ee7985c24ee6149f3a6175f44cec7a05b178c38bce9836d3ca48c9acb0329a960ac2c4b2ead4e60cdd4fe6e8c92cad7cd6913687 + languageName: node + linkType: hard + +"fast-stable-stringify@npm:^1.0.0": + version: 1.0.0 + resolution: "fast-stable-stringify@npm:1.0.0" + checksum: ef1203d246a7e8ac15e2bfbda0a89fa375947bccf9f7910be0ea759856dbe8ea5024a0d8cc2cceabe18a9cb67e95927b78bb6173a3ae37ec55a518cf36e5244b + languageName: node + linkType: hard + +"file-uri-to-path@npm:1.0.0": + version: 1.0.0 + resolution: "file-uri-to-path@npm:1.0.0" + checksum: b648580bdd893a008c92c7ecc96c3ee57a5e7b6c4c18a9a09b44fb5d36d79146f8e442578bc0e173dc027adf3987e254ba1dfd6e3ec998b7c282873010502144 + 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.0": + version: 1.15.2 + resolution: "follow-redirects@npm:1.15.2" + peerDependenciesMeta: + debug: + optional: true + checksum: faa66059b66358ba65c234c2f2a37fcec029dc22775f35d9ad6abac56003268baf41e55f9ee645957b32c7d9f62baf1f0b906e68267276f54ec4b4c597c2b190 + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.1.1 + resolution: "foreground-child@npm:3.1.1" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 139d270bc82dc9e6f8bc045fe2aae4001dc2472157044fdfad376d0a3457f77857fa883c1c8b21b491c6caade9a926a4bed3d3d2e8d3c9202b151a4cbbd0bcd5 + languageName: node + linkType: hard + +"form-data@npm:^4.0.0": + version: 4.0.0 + resolution: "form-data@npm:4.0.0" + dependencies: + asynckit: "npm:^0.4.0" + combined-stream: "npm:^1.0.8" + mime-types: "npm:^2.1.12" + checksum: 01135bf8675f9d5c61ff18e2e2932f719ca4de964e3be90ef4c36aacfc7b9cb2fceb5eca0b7e0190e3383fe51c5b37f4cb80b62ca06a99aaabfcfd6ac7c9328c + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 1b8d128dae2ac6cc94230cc5ead341ba3e0efaef82dab46a33d171c044caaa6ca001364178d42069b2809c35a1c3c35079a32107c770e9ffab3901b59af8c8b1 + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: 8722a41109130851d979222d3ec88aabaceeaaf8f57b2a8f744ef8bd2d1ce95453b04a61daa0078822bc5cd21e008814f06fe6586f56fef511e71b8d2394d802 + languageName: node + linkType: hard + +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 99ddea01a7e75aa276c250a04eedeffe5662bce66c65c07164ad6264f9de18fb21be9433ead460e54cff20e31721c811f4fb5d70591799df5f85dce6d6746fd0 + languageName: node + linkType: hard + +"gauge@npm:^4.0.3": + version: 4.0.4 + resolution: "gauge@npm:4.0.4" + dependencies: + aproba: "npm:^1.0.3 || ^2.0.0" + color-support: "npm:^1.1.3" + console-control-strings: "npm:^1.1.0" + has-unicode: "npm:^2.0.1" + signal-exit: "npm:^3.0.7" + string-width: "npm:^4.2.3" + strip-ansi: "npm:^6.0.1" + wide-align: "npm:^1.1.5" + checksum: 788b6bfe52f1dd8e263cda800c26ac0ca2ff6de0b6eee2fe0d9e3abf15e149b651bd27bf5226be10e6e3edb5c4e5d5985a5a1a98137e7a892f75eff76467ad2d + 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" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^2.0.3" + minimatch: "npm:^9.0.1" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry: "npm:^1.10.1" + bin: + glob: dist/cjs/src/bin.js + checksum: 29190d3291f422da0cb40b77a72fc8d2c51a36524e99b8bf412548b7676a6627489528b57250429612b6eec2e6fe7826d328451d3e694a9d15e575389308ec53 + languageName: node + linkType: hard + +"glob@npm:^7.1.3, glob@npm:^7.1.4": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.1.1" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133 + 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-unicode@npm:^2.0.1": + version: 2.0.1 + resolution: "has-unicode@npm:2.0.1" + checksum: 1eab07a7436512db0be40a710b29b5dc21fa04880b7f63c9980b706683127e3c1b57cb80ea96d47991bdae2dfe479604f6a1ba410106ee1046a41d1bd0814400 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 83ac0bc60b17a3a36f9953e7be55e5c8f41acc61b22583060e8dedc9dd5e3607c823a88d0926f9150e571f90946835c7fe150732801010845c72cd8bbff1a236 + languageName: node + linkType: hard + +"http-proxy-agent@npm:^5.0.0": + version: 5.0.0 + resolution: "http-proxy-agent@npm:5.0.0" + dependencies: + "@tootallnate/once": "npm:2" + agent-base: "npm:6" + debug: "npm:4" + checksum: e2ee1ff1656a131953839b2a19cd1f3a52d97c25ba87bd2559af6ae87114abf60971e498021f9b73f9fd78aea8876d1fb0d4656aac8a03c6caa9fc175f22b786 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^5.0.0": + version: 5.0.1 + resolution: "https-proxy-agent@npm:5.0.1" + dependencies: + agent-base: "npm:6" + debug: "npm:4" + checksum: 571fccdf38184f05943e12d37d6ce38197becdd69e58d03f43637f7fa1269cf303a7d228aa27e5b27bbd3af8f09fd938e1c91dcfefff2df7ba77c20ed8dfc765 + languageName: node + linkType: hard + +"humanize-ms@npm:^1.2.1": + version: 1.2.1 + resolution: "humanize-ms@npm:1.2.1" + dependencies: + ms: "npm:^2.0.0" + checksum: 9c7a74a2827f9294c009266c82031030eae811ca87b0da3dceb8d6071b9bde22c9f3daef0469c3c533cc67a97d8a167cd9fc0389350e5f415f61a79b171ded16 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 3f60d47a5c8fc3313317edfd29a00a692cc87a19cac0159e2ce711d0ebc9019064108323b5e493625e25594f11c6236647d8e256fbe7a58f4a3b33b89e6d30bf + languageName: node + linkType: hard + +"ieee754@npm:^1.2.1": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 7cae75c8cd9a50f57dadd77482359f659eaebac0319dd9368bcd1714f55e65badd6929ca58569da2b6494ef13fdd5598cd700b1eba23f8b79c5f19d195a3ecf7 + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: 824cfb9929d031dabf059bebfe08cf3137365e112019086ed3dcff6a0a7b698cb80cf67ccccde0e25b9e2d7527aa6cc1fed1ac490c752162496caba3e6699612 + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: f4f76aa072ce19fae87ce1ef7d221e709afb59d445e05d47fba710e85470923a75de35bfae47da6de1b18afc3ce83d70facf44cfb0aff89f0a3f45c0a0244dfd + languageName: node + linkType: hard + +"inherits@npm:2, inherits@npm:^2.0.3": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 + languageName: node + linkType: hard + +"ip@npm:^2.0.0": + version: 2.0.0 + resolution: "ip@npm:2.0.0" + checksum: cfcfac6b873b701996d71ec82a7dd27ba92450afdb421e356f44044ed688df04567344c36cbacea7d01b1c39a4c732dc012570ebe9bebfb06f27314bca625349 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 + 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" + checksum: 26bf6c5480dda5161c820c5b5c751ae1e766c587b1f951ea3fcfc973bafb7831ae5b54a31a69bd670220e42e99ec154475025a468eae58ea262f813fdc8d1c62 + languageName: node + linkType: hard + +"isomorphic-ws@npm:^4.0.1": + version: 4.0.1 + resolution: "isomorphic-ws@npm:4.0.1" + peerDependencies: + ws: "*" + checksum: d7190eadefdc28bdb93d67b5f0c603385aaf87724fa2974abb382ac1ec9756ed2cfb27065cbe76122879c2d452e2982bc4314317f3d6c737ddda6c047328771a + languageName: node + linkType: hard + +"jackspeak@npm:^2.0.3": + version: 2.3.1 + resolution: "jackspeak@npm:2.3.1" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 34ea4d618d8d36ac104fe1053c85dfb6a63306cfe87e157ef42f18a7aa30027887370a4e163dd4993e45c6bf8a8ae003bf8476fdb8538e8ee5cd1938c27b15d0 + languageName: node + linkType: hard + +"jayson@npm:^4.1.0": + version: 4.1.0 + resolution: "jayson@npm:4.1.0" + dependencies: + "@types/connect": "npm:^3.4.33" + "@types/node": "npm:^12.12.54" + "@types/ws": "npm:^7.4.4" + JSONStream: "npm:^1.3.5" + commander: "npm:^2.20.3" + delay: "npm:^5.0.0" + es6-promisify: "npm:^5.0.0" + eyes: "npm:^0.1.8" + isomorphic-ws: "npm:^4.0.1" + json-stringify-safe: "npm:^5.0.1" + uuid: "npm:^8.3.2" + ws: "npm:^7.4.5" + bin: + jayson: bin/jayson.js + checksum: 86464322fbdc6db65d2bb4fc278cb6c86fad5c2a506065490d39459f09ba0d30f2b4fb740b33828a1424791419b6c8bd295dc54d361a4ad959bf70cc62b1ca7e + 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" + checksum: 48ec0adad5280b8a96bb93f4563aa1667fd7a36334f79149abd42446d0989f2ddc58274b479f4819f1f00617957e6344c886c55d05a4e15ebb4ab931e4a6a8ee + languageName: node + linkType: hard + +"jsonparse@npm:^1.2.0": + version: 1.3.1 + resolution: "jsonparse@npm:1.3.1" + checksum: 6514a7be4674ebf407afca0eda3ba284b69b07f9958a8d3113ef1005f7ec610860c312be067e450c569aab8b89635e332cee3696789c750692bb60daba627f4d + languageName: node + linkType: hard + +"lower-case@npm:^2.0.2": + version: 2.0.2 + resolution: "lower-case@npm:2.0.2" + dependencies: + tslib: "npm:^2.0.3" + checksum: 83a0a5f159ad7614bee8bf976b96275f3954335a84fad2696927f609ddae902802c4f3312d86668722e668bef41400254807e1d3a7f2e8c3eede79691aa1f010 + languageName: node + linkType: hard + +"lru-cache@npm:^6.0.0": + version: 6.0.0 + resolution: "lru-cache@npm:6.0.0" + dependencies: + yallist: "npm:^4.0.0" + checksum: f97f499f898f23e4585742138a22f22526254fdba6d75d41a1c2526b3b6cc5747ef59c5612ba7375f42aca4f8461950e925ba08c991ead0651b4918b7c978297 + languageName: node + linkType: hard + +"lru-cache@npm:^7.7.1": + version: 7.18.3 + resolution: "lru-cache@npm:7.18.3" + checksum: e550d772384709deea3f141af34b6d4fa392e2e418c1498c078de0ee63670f1f46f5eee746e8ef7e69e1c895af0d4224e62ee33e66a543a14763b0f2e74c1356 + languageName: node + linkType: hard + +"lru-cache@npm:^9.1.1 || ^10.0.0": + version: 10.0.1 + resolution: "lru-cache@npm:10.0.1" + checksum: 06f8d0e1ceabd76bb6f644a26dbb0b4c471b79c7b514c13c6856113879b3bf369eb7b497dad4ff2b7e2636db202412394865b33c332100876d838ad1372f0181 + languageName: node + linkType: hard + +"make-error@npm:^1.1.1": + version: 1.3.6 + resolution: "make-error@npm:1.3.6" + checksum: b86e5e0e25f7f777b77fabd8e2cbf15737972869d852a22b7e73c17623928fccb826d8e46b9951501d3f20e51ad74ba8c59ed584f610526a48f8ccf88aaec402 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^11.0.3": + version: 11.1.1 + resolution: "make-fetch-happen@npm:11.1.1" + dependencies: + agentkeepalive: "npm:^4.2.1" + cacache: "npm:^17.0.0" + http-cache-semantics: "npm:^4.1.1" + http-proxy-agent: "npm:^5.0.0" + https-proxy-agent: "npm:^5.0.0" + is-lambda: "npm:^1.0.1" + lru-cache: "npm:^7.7.1" + minipass: "npm:^5.0.0" + minipass-fetch: "npm:^3.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^0.6.3" + promise-retry: "npm:^2.0.1" + socks-proxy-agent: "npm:^7.0.0" + ssri: "npm:^10.0.0" + checksum: 7268bf274a0f6dcf0343829489a4506603ff34bd0649c12058753900b0eb29191dce5dba12680719a5d0a983d3e57810f594a12f3c18494e93a1fbc6348a4540 + 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" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a + languageName: node + linkType: hard + +"minimatch@npm:^9.0.1": + version: 9.0.3 + resolution: "minimatch@npm:9.0.3" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 253487976bf485b612f16bf57463520a14f512662e592e95c571afdab1442a6a6864b6c88f248ce6fc4ff0b6de04ac7aa6c8bb51e868e99d1d65eb0658a708b5 + languageName: node + linkType: hard + +"minipass-collect@npm:^1.0.2": + version: 1.0.2 + resolution: "minipass-collect@npm:1.0.2" + dependencies: + minipass: "npm:^3.0.0" + checksum: 14df761028f3e47293aee72888f2657695ec66bd7d09cae7ad558da30415fdc4752bbfee66287dcc6fd5e6a2fa3466d6c484dc1cbd986525d9393b9523d97f10 + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.4 + resolution: "minipass-fetch@npm:3.0.4" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^2.1.2" + dependenciesMeta: + encoding: + optional: true + checksum: af7aad15d5c128ab1ebe52e043bdf7d62c3c6f0cecb9285b40d7b395e1375b45dcdfd40e63e93d26a0e8249c9efd5c325c65575aceee192883970ff8cb11364a + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 79076749fcacf21b5d16dd596d32c3b6bf4d6e62abb43868fac21674078505c8b15eaca4e47ed844985a4514854f917d78f588fcd029693709417d8f98b2bd60 + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: a30d083c8054cee83cdcdc97f97e4641a3f58ae743970457b1489ce38ee1167b3aaf7d815cd39ec7a99b9c40397fd4f686e83750e73e652b21cb516f6d845e48 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 425dab288738853fded43da3314a0b5c035844d6f3097a8e3b5b29b328da8f3c1af6fc70618b32c29ff906284cf6406b6841376f21caaadd0793c1d5a6a620ea + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.3": + version: 7.0.3 + resolution: "minipass@npm:7.0.3" + checksum: 6f1614f5b5b55568a46bca5fec0e7c46dac027691db27d0e1923a8192866903144cd962ac772c0e9f89b608ea818b702709c042bce98e190d258847d85461531 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: f1fdeac0b07cf8f30fcf12f4b586795b97be856edea22b5e9072707be51fc95d41487faec3f265b42973a304fe3a64acd91a44a3826a963e37b37bafde0212c3 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: a96865108c6c3b1b8e1d5e9f11843de1e077e57737602de1b82030815f311be11f96f09cce59bd5b903d0b29834733e5313f9301e3ed6d6f6fba2eae0df4298f + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + languageName: node + linkType: hard + +"ms@npm:^2.0.0": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d + 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" + checksum: b8ffeb1e262eff7968fc90a2b6767b04cfd9842582a9d0ece0af7049537266e7b2506dfb1d107a32f06dd849ab2aea834d5830f7f4d0e5cb7d36e1ae55d021d9 + languageName: node + linkType: hard + +"no-case@npm:^3.0.4": + version: 3.0.4 + resolution: "no-case@npm:3.0.4" + dependencies: + lower-case: "npm:^2.0.2" + tslib: "npm:^2.0.3" + checksum: 0b2ebc113dfcf737d48dde49cfebf3ad2d82a8c3188e7100c6f375e30eafbef9e9124aadc3becef237b042fd5eb0aad2fd78669c20972d045bbe7fea8ba0be5c + languageName: node + linkType: hard + +"node-fetch@npm:^2.6.12, node-fetch@npm:^2.7.0": + version: 2.7.0 + resolution: "node-fetch@npm:2.7.0" + dependencies: + whatwg-url: "npm:^5.0.0" + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: d76d2f5edb451a3f05b15115ec89fc6be39de37c6089f1b6368df03b91e1633fd379a7e01b7ab05089a25034b2023d959b47e59759cb38d88341b2459e89d6e5 + languageName: node + linkType: hard + +"node-gyp-build@npm:^4.3.0": + version: 4.6.1 + resolution: "node-gyp-build@npm:4.6.1" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: c3676d337b36803bc7792e35bf7fdcda7cdcb7e289b8f9855a5535702a82498eb976842fefcf487258c58005ca32ce3d537fbed91280b04409161dcd7232a882 + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 9.4.0 + resolution: "node-gyp@npm:9.4.0" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^7.1.4" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^11.0.3" + nopt: "npm:^6.0.0" + npmlog: "npm:^6.0.0" + rimraf: "npm:^3.0.2" + semver: "npm:^7.3.5" + tar: "npm:^6.1.2" + which: "npm:^2.0.2" + bin: + node-gyp: bin/node-gyp.js + checksum: 78b404e2e0639d64e145845f7f5a3cb20c0520cdaf6dda2f6e025e9b644077202ea7de1232396ba5bde3fee84cdc79604feebe6ba3ec84d464c85d407bb5da99 + languageName: node + linkType: hard + +"nopt@npm:^6.0.0": + version: 6.0.0 + resolution: "nopt@npm:6.0.0" + dependencies: + abbrev: "npm:^1.0.0" + bin: + nopt: bin/nopt.js + checksum: 82149371f8be0c4b9ec2f863cc6509a7fd0fa729929c009f3a58e4eb0c9e4cae9920e8f1f8eb46e7d032fec8fb01bede7f0f41a67eb3553b7b8e14fa53de1dac + languageName: node + linkType: hard + +"npmlog@npm:^6.0.0": + version: 6.0.2 + resolution: "npmlog@npm:6.0.2" + dependencies: + are-we-there-yet: "npm:^3.0.0" + console-control-strings: "npm:^1.1.0" + gauge: "npm:^4.0.3" + set-blocking: "npm:^2.0.0" + checksum: ae238cd264a1c3f22091cdd9e2b106f684297d3c184f1146984ecbe18aaa86343953f26b9520dedd1b1372bc0316905b736c1932d778dbeb1fcf5a1001390e2a + languageName: node + linkType: hard + +"once@npm:^1.3.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: cb0ab21ec0f32ddffd31dfc250e3afa61e103ef43d957cc45497afe37513634589316de4eb88abdfd969fe6410c22c0b93ab24328833b8eb1ccc087fc0442a1c + 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" + checksum: 060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8 + languageName: node + linkType: hard + +"path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + languageName: node + linkType: hard + +"path-scurry@npm:^1.10.1": + version: 1.10.1 + resolution: "path-scurry@npm:1.10.1" + dependencies: + lru-cache: "npm:^9.1.1 || ^10.0.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: e2557cff3a8fb8bc07afdd6ab163a92587884f9969b05bbbaf6fe7379348bfb09af9ed292af12ed32398b15fb443e81692047b786d1eeb6d898a51eb17ed7d90 + 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" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: f96a3f6d90b92b568a26f71e966cbbc0f63ab85ea6ff6c81284dc869b41510e6cdef99b6b65f9030f0db422bf7c96652a3fff9f2e8fb4a0f069d8f4430359429 + 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" + dependencies: + inherits: "npm:^2.0.3" + string_decoder: "npm:^1.1.1" + util-deprecate: "npm:^1.0.1" + checksum: bdcbe6c22e846b6af075e32cf8f4751c2576238c5043169a1c221c92ee2878458a816a4ea33f4c67623c0b6827c8a400409bfb3cf0bf3381392d0b1dfb52ac8d + languageName: node + linkType: hard + +"regenerator-runtime@npm:^0.14.0": + version: 0.14.0 + resolution: "regenerator-runtime@npm:0.14.0" + checksum: 1c977ad82a82a4412e4f639d65d22be376d3ebdd30da2c003eeafdaaacd03fc00c2320f18120007ee700900979284fc78a9f00da7fb593f6e6eeebc673fba9a3 + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 623bd7d2e5119467ba66202d733ec3c2e2e26568074923bc0585b6b99db14f357e79bdedb63cab56cec47491c4a0da7e6021a7465ca6dc4f481d3898fdd3158c + languageName: node + linkType: hard + +"rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: bin.js + checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0 + languageName: node + linkType: hard + +"rpc-websockets@npm:^7.5.1": + version: 7.6.0 + resolution: "rpc-websockets@npm:7.6.0" + dependencies: + "@babel/runtime": "npm:^7.17.2" + bufferutil: "npm:^4.0.1" + eventemitter3: "npm:^4.0.7" + utf-8-validate: "npm:^5.0.2" + uuid: "npm:^8.3.2" + ws: "npm:^8.5.0" + dependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: af2b254f65985610bd354e8e13de07b5a36010b94672b0b5a9d226b9bb1b8b17d01c63221cad97263845888f3610e55867a32e4c0017dfb92fddf89417c4cb6c + languageName: node + linkType: hard + +"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0 + languageName: node + linkType: hard + +"semver@npm:^7.3.4, semver@npm:^7.3.5": + version: 7.5.4 + resolution: "semver@npm:7.5.4" + dependencies: + lru-cache: "npm:^6.0.0" + bin: + semver: bin/semver.js + checksum: 12d8ad952fa353b0995bf180cdac205a4068b759a140e5d3c608317098b3575ac2f1e09182206bf2eb26120e1c0ed8fb92c48c592f6099680de56bb071423ca3 + languageName: node + linkType: hard + +"set-blocking@npm:^2.0.0": + version: 2.0.0 + resolution: "set-blocking@npm:2.0.0" + checksum: 6e65a05f7cf7ebdf8b7c75b101e18c0b7e3dff4940d480efed8aad3a36a4005140b660fa1d804cb8bce911cac290441dc728084a30504d3516ac2ff7ad607b02 + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.7": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 64c757b498cb8629ffa5f75485340594d2f8189e9b08700e69199069c8e3070fb3e255f7ab873c05dc0b3cec412aea7402e10a5990cb6a050bd33ba062a6c549 + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: b5167a7142c1da704c0e3af85c402002b597081dd9575031a90b4f229ca5678e9a36e8a374f1814c8156a725d17008ae3bde63b92f9cfd132526379e580bec8b + languageName: node + linkType: hard + +"snake-case@npm:^3.0.4": + version: 3.0.4 + resolution: "snake-case@npm:3.0.4" + dependencies: + dot-case: "npm:^3.0.4" + tslib: "npm:^2.0.3" + checksum: 0a7a79900bbb36f8aaa922cf111702a3647ac6165736d5dc96d3ef367efc50465cac70c53cd172c382b022dac72ec91710608e5393de71f76d7142e6fd80e8a3 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^7.0.0": + version: 7.0.0 + resolution: "socks-proxy-agent@npm:7.0.0" + dependencies: + agent-base: "npm:^6.0.2" + debug: "npm:^4.3.3" + socks: "npm:^2.6.2" + checksum: 720554370154cbc979e2e9ce6a6ec6ced205d02757d8f5d93fe95adae454fc187a5cbfc6b022afab850a5ce9b4c7d73e0f98e381879cf45f66317a4895953846 + languageName: node + linkType: hard + +"socks@npm:^2.6.2": + version: 2.7.1 + resolution: "socks@npm:2.7.1" + dependencies: + ip: "npm:^2.0.0" + smart-buffer: "npm:^4.2.0" + checksum: 259d9e3e8e1c9809a7f5c32238c3d4d2a36b39b83851d0f573bfde5f21c4b1288417ce1af06af1452569cd1eb0841169afd4998f0e04ba04656f6b7f0e46d748 + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.5 + resolution: "ssri@npm:10.0.5" + dependencies: + minipass: "npm:^7.0.3" + checksum: 0a31b65f21872dea1ed3f7c200d7bc1c1b91c15e419deca14f282508ba917cbb342c08a6814c7f68ca4ca4116dd1a85da2bbf39227480e50125a1ceffeecb750 + 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": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + languageName: node + linkType: hard + +"string_decoder@npm:^1.1.1": + version: 1.3.0 + resolution: "string_decoder@npm:1.3.0" + dependencies: + safe-buffer: "npm:~5.2.0" + checksum: 8417646695a66e73aefc4420eb3b84cc9ffd89572861fe004e6aeb13c7bc00e2f616247505d2dbbef24247c372f70268f594af7126f43548565c68c117bdeb56 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 859c73fcf27869c22a4e4d8c6acfe690064659e84bef9458aa6d13719d09ca88dcfd40cbf31fd0be63518ea1a643fe070b4827d353e09533a5b0b9fd4553d64d + languageName: node + linkType: hard + +"superstruct@npm:^0.14.2": + version: 0.14.2 + resolution: "superstruct@npm:0.14.2" + checksum: c5c4840f432da82125b923ec45faca5113217e83ae416e314d80eae012b8bb603d2e745025d173450758d116348820bc7028157f8c9a72b6beae879f94b837c0 + 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 + +"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" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: f23832fceeba7578bf31907aac744ae21e74a66f4a17a9e94507acf460e48f6db598c7023882db33bab75b80e027c21f276d405e4a0322d58f51c7088d428268 + languageName: node + linkType: hard + +"text-encoding-utf-8@npm:^1.0.2": + version: 1.0.2 + resolution: "text-encoding-utf-8@npm:1.0.2" + checksum: ec4c15d50e738c5dba7327ad432ebf0725ec75d4d69c0bd55609254c5a3bc5341272d7003691084a0a73d60d981c8eb0e87603676fdb6f3fed60f4c9192309f9 + languageName: node + linkType: hard + +"through@npm:>=2.2.7 <3": + version: 2.3.8 + resolution: "through@npm:2.3.8" + checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd + 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" + checksum: 726321c5eaf41b5002e17ffbd1fb7245999a073e8979085dacd47c4b4e8068ff5777142fc6726d6ca1fd2ff16921b48788b87225cbc57c72636f6efa8efbffe3 + 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 + +"ts-node@npm:^10.9.1": + version: 10.9.1 + resolution: "ts-node@npm:10.9.1" + dependencies: + "@cspotcode/source-map-support": "npm:^0.8.0" + "@tsconfig/node10": "npm:^1.0.7" + "@tsconfig/node12": "npm:^1.0.7" + "@tsconfig/node14": "npm:^1.0.0" + "@tsconfig/node16": "npm:^1.0.2" + acorn: "npm:^8.4.1" + acorn-walk: "npm:^8.1.1" + arg: "npm:^4.1.0" + create-require: "npm:^1.1.0" + diff: "npm:^4.0.1" + make-error: "npm:^1.1.1" + v8-compile-cache-lib: "npm:^3.0.1" + yn: "npm:3.1.1" + peerDependencies: + "@swc/core": ">=1.2.50" + "@swc/wasm": ">=1.2.50" + "@types/node": "*" + typescript: ">=2.7" + peerDependenciesMeta: + "@swc/core": + optional: true + "@swc/wasm": + optional: true + bin: + ts-node: dist/bin.js + ts-node-cwd: dist/bin-cwd.js + ts-node-esm: dist/bin-esm.js + ts-node-script: dist/bin-script.js + ts-node-transpile-only: dist/bin-transpile.js + ts-script: dist/bin-script-deprecated.js + checksum: 090adff1302ab20bd3486e6b4799e90f97726ed39e02b39e566f8ab674fd5bd5f727f43615debbfc580d33c6d9d1c6b1b3ce7d8e3cca3e20530a145ffa232c35 + languageName: node + linkType: hard + +"tslib@npm:^2.0.3": + version: 2.6.2 + resolution: "tslib@npm:2.6.2" + checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad + 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" + dependencies: + unique-slug: "npm:^4.0.0" + checksum: 8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 0884b58365af59f89739e6f71e3feacb5b1b41f2df2d842d0757933620e6de08eff347d27e9d499b43c40476cbaf7988638d3acb2ffbcb9d35fd035591adfd15 + languageName: node + linkType: hard + +"utf-8-validate@npm:^5.0.2": + version: 5.0.10 + resolution: "utf-8-validate@npm:5.0.10" + dependencies: + node-gyp: "npm:latest" + node-gyp-build: "npm:^4.3.0" + checksum: 5579350a023c66a2326752b6c8804cc7b39dcd251bb088241da38db994b8d78352e388dcc24ad398ab98385ba3c5ffcadb6b5b14b2637e43f767869055e46ba6 + languageName: node + linkType: hard + +"util-deprecate@npm:^1.0.1": + version: 1.0.2 + resolution: "util-deprecate@npm:1.0.2" + checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 + languageName: node + linkType: hard + +"uuid@npm:^8.3.2": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" + bin: + uuid: dist/bin/uuid + checksum: 5575a8a75c13120e2f10e6ddc801b2c7ed7d8f3c8ac22c7ed0c7b2ba6383ec0abda88c905085d630e251719e0777045ae3236f04c812184b7c765f63a70e58df + languageName: node + linkType: hard + +"v8-compile-cache-lib@npm:^3.0.1": + version: 3.0.1 + resolution: "v8-compile-cache-lib@npm:3.0.1" + checksum: 78089ad549e21bcdbfca10c08850022b22024cdcc2da9b168bcf5a73a6ed7bf01a9cebb9eac28e03cd23a684d81e0502797e88f3ccd27a32aeab1cfc44c39da0 + languageName: node + linkType: hard + +"webidl-conversions@npm:^3.0.0": + version: 3.0.1 + resolution: "webidl-conversions@npm:3.0.1" + checksum: c92a0a6ab95314bde9c32e1d0a6dfac83b578f8fa5f21e675bc2706ed6981bc26b7eb7e6a1fab158e5ce4adf9caa4a0aee49a52505d4d13c7be545f15021b17c + languageName: node + linkType: hard + +"whatwg-url@npm:^5.0.0": + version: 5.0.0 + resolution: "whatwg-url@npm:5.0.0" + dependencies: + tr46: "npm:~0.0.3" + webidl-conversions: "npm:^3.0.0" + checksum: b8daed4ad3356cc4899048a15b2c143a9aed0dfae1f611ebd55073310c7b910f522ad75d727346ad64203d7e6c79ef25eafd465f4d12775ca44b90fa82ed9e2c + languageName: node + linkType: hard + +"which@npm:^2.0.1, which@npm:^2.0.2": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 1a5c563d3c1b52d5f893c8b61afe11abc3bab4afac492e8da5bde69d550de701cf9806235f20a47b5c8fa8a1d6a9135841de2596535e998027a54589000e66d1 + languageName: node + linkType: hard + +"wide-align@npm:^1.1.5": + version: 1.1.5 + resolution: "wide-align@npm:1.1.5" + dependencies: + string-width: "npm:^1.0.2 || 2 || 3 || 4" + checksum: d5fc37cd561f9daee3c80e03b92ed3e84d80dde3365a8767263d03dacfc8fa06b065ffe1df00d8c2a09f731482fcacae745abfbb478d4af36d0a891fad4834d3 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 371733296dc2d616900ce15a0049dca0ef67597d6394c57347ba334393599e800bab03c41d4d45221b6bc967b8c453ec3ae4749eff3894202d16800fdfe0e238 + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 + languageName: node + linkType: hard + +"ws@npm:^7.4.5": + version: 7.5.9 + resolution: "ws@npm:7.5.9" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: c3c100a181b731f40b7f2fddf004aa023f79d64f489706a28bc23ff88e87f6a64b3c6651fbec3a84a53960b75159574d7a7385709847a62ddb7ad6af76f49138 + languageName: node + linkType: hard + +"ws@npm:^8.5.0": + version: 8.13.0 + resolution: "ws@npm:8.13.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 53e991bbf928faf5dc6efac9b8eb9ab6497c69feeb94f963d648b7a3530a720b19ec2e0ec037344257e05a4f35bd9ad04d9de6f289615ffb133282031b18c61c + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5 + 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 diff --git a/packages/rewards-oracle-faucet-service/.env b/packages/rewards-oracle-faucet-service/.env new file mode 100644 index 000000000..fca0da9bc --- /dev/null +++ b/packages/rewards-oracle-faucet-service/.env @@ -0,0 +1,3 @@ +PGUSER=postgres +PGDATABASE=postgres +PGPASSWORD=postgres diff --git a/packages/spl-utils/src/constants.ts b/packages/spl-utils/src/constants.ts index 31c6cb932..8f29054f5 100644 --- a/packages/spl-utils/src/constants.ts +++ b/packages/spl-utils/src/constants.ts @@ -22,3 +22,11 @@ export const HELIUM_COMMON_LUT_DEVNET = new PublicKey( export const HELIUM_COMMON_LUT = new PublicKey( "43eY9L2spbM2b1MPDFFBStUiFGt29ziZ1nc1xbpzsfVt" ); + +export const MOBILE_PRICE_FEED = new PublicKey( + "DQ4C1tzvu28cwo1roN1Wm6TW35sfJEjLh517k3ZeWevx" +); + +export const IOT_PRICE_FEED = new PublicKey( + "8UYEn5Weq7toHwgcmctvcAxaNJo3SJxXEayM57rpoXr9" +); \ No newline at end of file diff --git a/programs/helium-entity-manager/src/instructions/initialize_shared_merkle_v0.rs b/programs/helium-entity-manager/src/instructions/initialize_shared_merkle_v0.rs new file mode 100644 index 000000000..134f502ba --- /dev/null +++ b/programs/helium-entity-manager/src/instructions/initialize_shared_merkle_v0.rs @@ -0,0 +1,83 @@ +use account_compression_cpi::{program::SplAccountCompression, Noop}; +use anchor_lang::prelude::*; +use bubblegum_cpi::cpi::{accounts::CreateTree, create_tree}; +use bubblegum_cpi::program::Bubblegum; + +use crate::{shared_merkle_seeds, state::SharedMerkleV0}; + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)] +pub struct InitializeSharedMerkleArgsV0 { + pub proof_size: u8, +} + +#[derive(Accounts)] +#[instruction(args: InitializeSharedMerkleArgsV0)] +pub struct InitializeSharedMerkleV0<'info> { + #[account(mut)] + pub payer: Signer<'info>, + #[account( + init, + seeds = [b"shared_merkle", &args.proof_size.to_le_bytes()[..]], + bump, + payer = payer, + space = 8 + SharedMerkleV0::INIT_SPACE + 32, + )] + pub shared_merkle: Account<'info, SharedMerkleV0>, + #[account( + mut, + seeds = [merkle_tree.key().as_ref()], + bump, + seeds::program = bubblegum_program.key() + )] + /// CHECK: Checked by cpi + pub tree_authority: AccountInfo<'info>, + /// CHECK: Checked by cpi + #[account(mut)] + pub merkle_tree: UncheckedAccount<'info>, + + pub system_program: Program<'info, System>, + pub log_wrapper: Program<'info, Noop>, + pub bubblegum_program: Program<'info, Bubblegum>, + pub compression_program: Program<'info, SplAccountCompression>, +} + +pub const STARTING_DEPTH: u32 = 17; +pub const BUFFER_SIZE: u32 = 64; + +fn div_ceil(dividend: u64, divisor: u64) -> u64 { + (dividend + divisor - 1) / divisor +} + +pub fn handler( + ctx: Context, + args: InitializeSharedMerkleArgsV0, +) -> Result<()> { + let depth = STARTING_DEPTH + args.proof_size as u32; + let total_lamports = ctx.accounts.merkle_tree.lamports() + ctx.accounts.tree_authority.lamports(); + ctx.accounts.shared_merkle.set_inner(SharedMerkleV0 { + proof_size: args.proof_size, + price_per_mint: div_ceil(total_lamports, 2u64.pow(depth) - 3), // because we can swap with 3 left + merkle_tree: ctx.accounts.merkle_tree.key(), + bump_seed: ctx.bumps["shared_merkle"], + }); + let signer_seeds = shared_merkle_seeds!(ctx.accounts.shared_merkle); + create_tree( + CpiContext::new_with_signer( + ctx.accounts.bubblegum_program.to_account_info().clone(), + CreateTree { + tree_authority: ctx.accounts.tree_authority.to_account_info().clone(), + merkle_tree: ctx.accounts.merkle_tree.to_account_info().clone(), + payer: ctx.accounts.payer.to_account_info().clone(), + tree_creator: ctx.accounts.shared_merkle.to_account_info().clone(), + log_wrapper: ctx.accounts.log_wrapper.to_account_info().clone(), + compression_program: ctx.accounts.compression_program.to_account_info().clone(), + system_program: ctx.accounts.system_program.to_account_info().clone(), + }, + &[signer_seeds], + ), + depth, + BUFFER_SIZE, + None, + )?; + Ok(()) +} diff --git a/programs/helium-entity-manager/src/instructions/issue_program_entity_v0.rs b/programs/helium-entity-manager/src/instructions/issue_program_entity_v0.rs index 8b7901af3..43e456c35 100644 --- a/programs/helium-entity-manager/src/instructions/issue_program_entity_v0.rs +++ b/programs/helium-entity-manager/src/instructions/issue_program_entity_v0.rs @@ -1,8 +1,10 @@ use crate::{constants::ENTITY_METADATA_URL, error::ErrorCode}; -use crate::{key_to_asset_seeds, state::*}; +use crate::{key_to_asset_seeds, shared_merkle_seeds, state::*}; use account_compression_cpi::{program::SplAccountCompression, Noop}; use anchor_lang::prelude::*; use anchor_lang::solana_program::hash::hash; +use anchor_lang::solana_program::program::invoke; +use anchor_lang::solana_program::system_instruction; use anchor_spl::token::Mint; use bubblegum_cpi::{ cpi::{accounts::MintToCollectionV1, mint_to_collection_v1}, @@ -103,6 +105,11 @@ pub struct IssueProgramEntityV0<'info> { pub bubblegum_program: Program<'info, Bubblegum>, pub compression_program: Program<'info, SplAccountCompression>, pub system_program: Program<'info, System>, + #[account( + mut, + has_one = merkle_tree + )] + pub shared_merkle: Option>, } impl<'info> IssueProgramEntityV0<'info> { @@ -113,7 +120,11 @@ impl<'info> IssueProgramEntityV0<'info> { leaf_owner: self.recipient.to_account_info(), merkle_tree: self.merkle_tree.to_account_info(), payer: self.payer.to_account_info(), - tree_delegate: self.program_approver.to_account_info(), + tree_delegate: self + .shared_merkle + .as_ref() + .map(|m| m.to_account_info()) + .unwrap_or(self.program_approver.to_account_info()), log_wrapper: self.log_wrapper.to_account_info(), compression_program: self.compression_program.to_account_info(), system_program: self.system_program.to_account_info(), @@ -203,14 +214,43 @@ pub fn handler(ctx: Context, args: IssueProgramEntityArgsV let mut key_to_asset_creator = ctx.accounts.key_to_asset.to_account_info(); key_to_asset_creator.is_signer = true; let key_to_asset_signer: &[&[u8]] = key_to_asset_seeds!(ctx.accounts.key_to_asset); - mint_to_collection_v1( - ctx - .accounts - .mint_to_collection_ctx() - .with_remaining_accounts(vec![creator, key_to_asset_creator]) - .with_signer(&[entity_creator_seeds[0], key_to_asset_signer]), - metadata, - )?; + if let Some(shared_merkle) = ctx.accounts.shared_merkle.as_ref() { + let shared_merkle_seeds = shared_merkle_seeds!(shared_merkle); + let transfer_instruction = system_instruction::transfer( + &ctx.accounts.payer.key(), + &shared_merkle.to_account_info().key(), + shared_merkle.price_per_mint, + ); + invoke( + &transfer_instruction, + &[ + ctx.accounts.payer.to_account_info(), + shared_merkle.to_account_info(), + ctx.accounts.system_program.to_account_info(), + ], + )?; + mint_to_collection_v1( + ctx + .accounts + .mint_to_collection_ctx() + .with_remaining_accounts(vec![creator, key_to_asset_creator]) + .with_signer(&[ + entity_creator_seeds[0], + key_to_asset_signer, + shared_merkle_seeds, + ]), + metadata, + )?; + } else { + mint_to_collection_v1( + ctx + .accounts + .mint_to_collection_ctx() + .with_remaining_accounts(vec![creator, key_to_asset_creator]) + .with_signer(&[entity_creator_seeds[0], key_to_asset_signer]), + metadata, + )?; + } Ok(()) } diff --git a/programs/helium-entity-manager/src/instructions/mod.rs b/programs/helium-entity-manager/src/instructions/mod.rs index 4612a289c..024f98bd0 100644 --- a/programs/helium-entity-manager/src/instructions/mod.rs +++ b/programs/helium-entity-manager/src/instructions/mod.rs @@ -3,6 +3,7 @@ pub mod approve_program_v0; pub mod initialize_data_only_v0; pub mod initialize_maker_v0; pub mod initialize_rewardable_entity_config_v0; +pub mod initialize_shared_merkle_v0; pub mod issue_data_only_entity_v0; pub mod issue_entity_v0; pub mod issue_iot_operations_fund_v0; @@ -15,6 +16,7 @@ pub mod revoke_maker_v0; pub mod revoke_program_v0; pub mod set_entity_active_v0; pub mod set_maker_tree_v0; +pub mod swap_shared_merkle_tree_v0; pub mod temp_pay_mobile_onboarding_fee_v0; pub mod temp_standardize_entity; pub mod update_data_only_tree_v0; @@ -29,6 +31,7 @@ pub use approve_program_v0::*; pub use initialize_data_only_v0::*; pub use initialize_maker_v0::*; pub use initialize_rewardable_entity_config_v0::*; +pub use initialize_shared_merkle_v0::*; pub use issue_data_only_entity_v0::*; pub use issue_entity_v0::*; pub use issue_iot_operations_fund_v0::*; @@ -41,6 +44,7 @@ pub use revoke_maker_v0::*; pub use revoke_program_v0::*; pub use set_entity_active_v0::*; pub use set_maker_tree_v0::*; +pub use swap_shared_merkle_tree_v0::*; pub use temp_pay_mobile_onboarding_fee_v0::*; pub use temp_standardize_entity::*; pub use update_data_only_tree_v0::*; diff --git a/programs/helium-entity-manager/src/instructions/swap_shared_merkle_tree_v0.rs b/programs/helium-entity-manager/src/instructions/swap_shared_merkle_tree_v0.rs new file mode 100644 index 000000000..57800d406 --- /dev/null +++ b/programs/helium-entity-manager/src/instructions/swap_shared_merkle_tree_v0.rs @@ -0,0 +1,81 @@ +use crate::{shared_merkle_seeds, state::*, BUFFER_SIZE, STARTING_DEPTH}; +use account_compression_cpi::{program::SplAccountCompression, Noop}; +use anchor_lang::prelude::*; +use bubblegum_cpi::{ + cpi::{accounts::CreateTree, create_tree}, + program::Bubblegum, + TreeConfig, +}; + +#[derive(Accounts)] +pub struct SwapSharedMerkleTreeV0<'info> { + #[account(mut)] + pub payer: Signer<'info>, + #[account(mut)] + pub shared_merkle: Box>, + #[account( + mut, + seeds = [shared_merkle.merkle_tree.key().as_ref()], + bump, + // Allow permissionlessly swapping trees when we're within 3 of full + constraint = tree_authority.num_minted > (tree_authority.total_mint_capacity - 3), + seeds::program = bubblegum_program.key() + )] + pub tree_authority: Box>, + #[account( + mut, + seeds = [new_merkle_tree.key().as_ref()], + bump, + seeds::program = bubblegum_program.key() + )] + /// CHECK: Checked by cpi + pub new_tree_authority: UncheckedAccount<'info>, + #[account(mut)] + /// CHECK: Checked by cpi + pub new_merkle_tree: AccountInfo<'info>, + + pub log_wrapper: Program<'info, Noop>, + pub system_program: Program<'info, System>, + pub bubblegum_program: Program<'info, Bubblegum>, + pub compression_program: Program<'info, SplAccountCompression>, +} + +pub fn handler(ctx: Context) -> Result<()> { + let signer_seeds: &[&[&[u8]]] = &[shared_merkle_seeds!(ctx.accounts.shared_merkle)]; + let depth = STARTING_DEPTH + ctx.accounts.shared_merkle.proof_size as u32; + + create_tree( + CpiContext::new_with_signer( + ctx.accounts.bubblegum_program.to_account_info().clone(), + CreateTree { + tree_authority: ctx.accounts.new_tree_authority.to_account_info().clone(), + merkle_tree: ctx.accounts.new_merkle_tree.to_account_info().clone(), + payer: ctx.accounts.payer.to_account_info().clone(), + tree_creator: ctx.accounts.shared_merkle.to_account_info().clone(), + log_wrapper: ctx.accounts.log_wrapper.to_account_info().clone(), + compression_program: ctx.accounts.compression_program.to_account_info().clone(), + system_program: ctx.accounts.system_program.to_account_info().clone(), + }, + signer_seeds, + ), + depth, + BUFFER_SIZE, + None, + )?; + ctx.accounts.shared_merkle.merkle_tree = ctx.accounts.new_merkle_tree.key(); + + let refund_lamports = + ctx.accounts.new_merkle_tree.lamports() + ctx.accounts.new_tree_authority.lamports(); + **ctx + .accounts + .shared_merkle + .to_account_info() + .try_borrow_mut_lamports()? -= refund_lamports; + **ctx + .accounts + .payer + .to_account_info() + .try_borrow_mut_lamports()? += refund_lamports; + + Ok(()) +} diff --git a/programs/helium-entity-manager/src/lib.rs b/programs/helium-entity-manager/src/lib.rs index 5ae721158..083e04585 100644 --- a/programs/helium-entity-manager/src/lib.rs +++ b/programs/helium-entity-manager/src/lib.rs @@ -32,6 +32,17 @@ security_txt! { pub mod helium_entity_manager { use super::*; + pub fn swap_shared_merkle_tree_v0(ctx: Context) -> Result<()> { + swap_shared_merkle_tree_v0::handler(ctx) + } + + pub fn initialize_shared_merkle_v0( + ctx: Context, + args: InitializeSharedMerkleArgsV0, + ) -> Result<()> { + initialize_shared_merkle_v0::handler(ctx, args) + } + pub fn initialize_rewardable_entity_config_v0( ctx: Context, args: InitializeRewardableEntityConfigArgsV0, diff --git a/programs/helium-entity-manager/src/state.rs b/programs/helium-entity-manager/src/state.rs index daec01135..9d884df97 100644 --- a/programs/helium-entity-manager/src/state.rs +++ b/programs/helium-entity-manager/src/state.rs @@ -331,3 +331,23 @@ macro_rules! key_to_asset_seeds { ] }; } + +#[account] +#[derive(Default, InitSpace)] +pub struct SharedMerkleV0 { + pub proof_size: u8, + pub price_per_mint: u64, + pub merkle_tree: Pubkey, + pub bump_seed: u8, +} + +#[macro_export] +macro_rules! shared_merkle_seeds { + ( $merkle:expr ) => { + &[ + b"shared_merkle".as_ref(), + &$merkle.proof_size.to_le_bytes()[..], + &[$merkle.bump_seed], + ] + }; +} diff --git a/programs/iot-routing-manager/Cargo.toml b/programs/iot-routing-manager/Cargo.toml new file mode 100644 index 000000000..cee0506d6 --- /dev/null +++ b/programs/iot-routing-manager/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "iot-routing-manager" +version = "0.1.2" +description = "Created with Anchor" +edition = "2021" + +[lib] +crate-type = ["cdylib", "lib"] +name = "iot_routing_manager" + +[features] +devnet = [] +no-genesis = [] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +cpi = ["no-entrypoint"] +default = [] + +[profile.release] +overflow-checks = true + +[dependencies] +bs58 = "0.3.1" +anchor-lang = { workspace = true } +anchor-spl = { workspace = true } +bytemuck = "1.12.3" +angry-purple-tiger = "0.1.0" +mpl-token-metadata = { workspace = true } +bubblegum-cpi = { workspace = true } +account-compression-cpi = { workspace = true } +shared-utils = { workspace = true } +helium-entity-manager = { workspace = true } +helium-sub-daos = { workspace = true } +solana-security-txt = { workspace = true } +default-env = { workspace = true } +pyth-solana-receiver-sdk = "0.3.0" +solana-program = "1.16.13" diff --git a/programs/iot-routing-manager/Xargo.toml b/programs/iot-routing-manager/Xargo.toml new file mode 100644 index 000000000..475fb71ed --- /dev/null +++ b/programs/iot-routing-manager/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] diff --git a/programs/iot-routing-manager/src/error.rs b/programs/iot-routing-manager/src/error.rs new file mode 100644 index 000000000..7af8d31e3 --- /dev/null +++ b/programs/iot-routing-manager/src/error.rs @@ -0,0 +1,19 @@ +use anchor_lang::prelude::*; + +#[error_code] +pub enum ErrorCode { + #[msg("The carrier is not approved")] + CarrierNotApproved, + #[msg("Names, symbols and urls must be less than 32, 10, and 200 characters respectively")] + InvalidStringLength, + #[msg("Cannot swap tree until it is close to full")] + TreeNotFull, + #[msg("Arithmetic error")] + ArithmeticError, + #[msg("Pyth price is not available")] + PythPriceNotFound, + #[msg("Pyth price is stale")] + PythPriceFeedStale, + #[msg("Organization is not approved")] + OrganizationNotApproved, +} diff --git a/programs/iot-routing-manager/src/instructions/approve_organization_v0.rs b/programs/iot-routing-manager/src/instructions/approve_organization_v0.rs new file mode 100644 index 000000000..07aa865f2 --- /dev/null +++ b/programs/iot-routing-manager/src/instructions/approve_organization_v0.rs @@ -0,0 +1,23 @@ +use anchor_lang::prelude::*; + +use crate::{NetIdV0, OrganizationV0}; + +#[derive(Accounts)] +pub struct ApproveOrganizationV0<'info> { + pub authority: Signer<'info>, + #[account( + has_one = authority + )] + pub net_id: Account<'info, NetIdV0>, + #[account( + mut, + has_one = net_id, + )] + pub organization: Account<'info, OrganizationV0>, + pub system_program: Program<'info, System>, +} + +pub fn handler(ctx: Context) -> Result<()> { + ctx.accounts.organization.approved = true; + Ok(()) +} diff --git a/programs/iot-routing-manager/src/instructions/initialize_devaddr_constraint_v0.rs b/programs/iot-routing-manager/src/instructions/initialize_devaddr_constraint_v0.rs new file mode 100644 index 000000000..b28351776 --- /dev/null +++ b/programs/iot-routing-manager/src/instructions/initialize_devaddr_constraint_v0.rs @@ -0,0 +1,145 @@ +use crate::error::ErrorCode; +use anchor_lang::{prelude::*, solana_program::pubkey}; +use anchor_spl::token::{burn, Burn, Mint, Token, TokenAccount}; +use pyth_solana_receiver_sdk::price_update::{PriceUpdateV2, VerificationLevel}; + +use crate::{DevAddrConstraintV0, IotRoutingManagerV0, NetIdV0, OrganizationV0}; + +pub const TESTING: bool = std::option_env!("TESTING").is_some(); + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)] +pub struct InitializeDevaddrConstraintArgsV0 { + pub num_blocks: u32, + /// Override the default start address for the devaddr constraint. + /// WARNING: This is dangerous and can create unvalidated overlap, + /// this should not happen under Helium managed net ids + pub start_addr: Option, +} + +pub const ADMIN_KEY: Pubkey = pubkey!("hprdnjkbziK8NqhThmAn5Gu4XqrBbctX8du4PfJdgvW"); +#[derive(Accounts)] +#[instruction(args: InitializeDevaddrConstraintArgsV0)] +pub struct InitializeDevaddrConstraintV0<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub authority: Signer<'info>, + #[account( + has_one = authority, + )] + pub net_id: Box>, + #[account( + has_one = iot_mint, + has_one = iot_price_oracle, + )] + pub routing_manager: Box>, + #[account( + has_one = net_id, + has_one = routing_manager, + constraint = organization.approved @ ErrorCode::OrganizationNotApproved, + )] + pub organization: Box>, + #[account(mut)] + pub iot_mint: Box>, + #[account( + mut, + associated_token::mint = iot_mint, + associated_token::authority = payer, + )] + pub payer_iot_account: Box>, + #[account( + constraint = iot_price_oracle.verification_level == VerificationLevel::Full @ ErrorCode::PythPriceFeedStale, + )] + pub iot_price_oracle: Box>, + #[account( + init, + payer = payer, + seeds = [b"devaddr_constraint", organization.key().as_ref(), &args.start_addr.unwrap_or(net_id.current_addr_offset).to_le_bytes()[..]], + bump, + space = 8 + DevAddrConstraintV0::INIT_SPACE + 60 + )] + pub devaddr_constraint: Box>, + pub token_program: Program<'info, Token>, + pub system_program: Program<'info, System>, +} + +pub fn handler( + ctx: Context, + args: InitializeDevaddrConstraintArgsV0, +) -> Result<()> { + let start_addr = args + .start_addr + .unwrap_or(ctx.accounts.net_id.current_addr_offset); + let end_addr = start_addr + (args.num_blocks * 8) as u64; + if end_addr > ctx.accounts.net_id.current_addr_offset { + ctx.accounts.net_id.current_addr_offset = end_addr; + } + + let message = ctx.accounts.iot_price_oracle.price_message; + let current_time = Clock::get()?.unix_timestamp; + require_gte!( + message + .publish_time + .saturating_add(if TESTING { 6000000 } else { 10 * 60 }.into()), + current_time, + ErrorCode::PythPriceNotFound + ); + let iot_price = message.ema_price; + require_gt!(iot_price, 0); + + // Remove the confidence from the price to use the most conservative price + // https://docs.pyth.network/price-feeds/solana-price-feeds/best-practices#confidence-intervals + let iot_price_with_conf = iot_price + .checked_sub(i64::try_from(message.ema_conf.checked_mul(2).unwrap()).unwrap()) + .unwrap(); + // Exponent is a negative number, likely -8 + // Since the price is multiplied by an extra 10^8, and we're dividing by that price, need to also multiply + // by the exponent + let exponent_dec = 10_u64 + .checked_pow(u32::try_from(-message.exponent).unwrap()) + .ok_or_else(|| error!(ErrorCode::ArithmeticError))?; + + require_gt!(iot_price_with_conf, 0); + let iot_fee = ctx + .accounts + .routing_manager + .devaddr_price_usd + .checked_mul(exponent_dec) + .unwrap() + .checked_div(iot_price_with_conf.try_into().unwrap()) + .unwrap() + .checked_mul( + end_addr + .checked_sub(start_addr) + .unwrap() + .checked_div(8) + .unwrap(), + ) + .unwrap(); + // TEMP: Admin doesn't have to burn, that way we can backfill + if iot_fee > 0 && ctx.accounts.payer.key() != ADMIN_KEY { + burn( + CpiContext::new( + ctx.accounts.token_program.to_account_info(), + Burn { + mint: ctx.accounts.iot_mint.to_account_info(), + from: ctx.accounts.payer_iot_account.to_account_info(), + authority: ctx.accounts.payer.to_account_info(), + }, + ), + iot_fee, + )?; + } + + ctx + .accounts + .devaddr_constraint + .set_inner(DevAddrConstraintV0 { + routing_manager: ctx.accounts.net_id.routing_manager, + net_id: ctx.accounts.net_id.key(), + organization: ctx.accounts.organization.key(), + start_addr: start_addr, + end_addr, + bump_seed: ctx.bumps["devaddr_constraint"], + }); + Ok(()) +} diff --git a/programs/iot-routing-manager/src/instructions/initialize_net_id_v0.rs b/programs/iot-routing-manager/src/instructions/initialize_net_id_v0.rs new file mode 100644 index 000000000..8e07b6e66 --- /dev/null +++ b/programs/iot-routing-manager/src/instructions/initialize_net_id_v0.rs @@ -0,0 +1,42 @@ +use anchor_lang::prelude::*; + +use crate::{IotRoutingManagerV0, NetIdV0}; + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)] +pub struct InitializeNetIdArgsV0 { + pub net_id: u64, +} + +#[derive(Accounts)] +#[instruction(args: InitializeNetIdArgsV0)] +pub struct InitializeNetIdV0<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub net_id_authority: Signer<'info>, + /// CHECK: The authority of the net id + pub authority: AccountInfo<'info>, + #[account( + has_one = net_id_authority + )] + pub routing_manager: Account<'info, IotRoutingManagerV0>, + #[account( + init, + payer = payer, + space = 8 + NetIdV0::INIT_SPACE + 60, + seeds = [b"net_id", routing_manager.key().as_ref(), &args.net_id.to_le_bytes()[..]], + bump, + )] + pub net_id: Account<'info, NetIdV0>, + pub system_program: Program<'info, System>, +} + +pub fn handler(ctx: Context, args: InitializeNetIdArgsV0) -> Result<()> { + ctx.accounts.net_id.set_inner(NetIdV0 { + id: args.net_id, + routing_manager: ctx.accounts.routing_manager.key(), + authority: ctx.accounts.authority.key(), + current_addr_offset: 0, + bump_seed: ctx.bumps["net_id"], + }); + Ok(()) +} diff --git a/programs/iot-routing-manager/src/instructions/initialize_organization_delegate_v0.rs b/programs/iot-routing-manager/src/instructions/initialize_organization_delegate_v0.rs new file mode 100644 index 000000000..98c60a9da --- /dev/null +++ b/programs/iot-routing-manager/src/instructions/initialize_organization_delegate_v0.rs @@ -0,0 +1,37 @@ +use anchor_lang::prelude::*; + +use crate::{OrganizationDelegateV0, OrganizationV0}; + +#[derive(Accounts)] +pub struct InitializeOrganizationDelegateV0<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub authority: Signer<'info>, + #[account( + has_one = authority + )] + pub organization: Account<'info, OrganizationV0>, + #[account( + init, + payer = payer, + space = 8 + OrganizationDelegateV0::INIT_SPACE + 32, + seeds = [b"organization_delegate", organization.key().as_ref(), delegate.key().as_ref()], + bump, + )] + pub organization_delegate: Account<'info, OrganizationDelegateV0>, + /// CHECK: The actual account that will act as a delegate + pub delegate: AccountInfo<'info>, + pub system_program: Program<'info, System>, +} + +pub fn handler(ctx: Context) -> Result<()> { + ctx + .accounts + .organization_delegate + .set_inner(OrganizationDelegateV0 { + organization: ctx.accounts.organization.key(), + delegate: ctx.accounts.delegate.key(), + bump_seed: ctx.bumps["organization_delegate"], + }); + Ok(()) +} diff --git a/programs/iot-routing-manager/src/instructions/initialize_organization_v0.rs b/programs/iot-routing-manager/src/instructions/initialize_organization_v0.rs new file mode 100644 index 000000000..3cba93b3f --- /dev/null +++ b/programs/iot-routing-manager/src/instructions/initialize_organization_v0.rs @@ -0,0 +1,265 @@ +use crate::error::ErrorCode; +use crate::{net_id_seeds, routing_manager_seeds, state::*, ADMIN_KEY, TESTING}; +use account_compression_cpi::{program::SplAccountCompression, Noop}; +use anchor_lang::prelude::*; +use anchor_lang::solana_program::hash::hash; +use anchor_spl::token::{burn, Burn, Mint, Token, TokenAccount}; +use bubblegum_cpi::program::Bubblegum; +use bubblegum_cpi::TreeConfig; +use helium_entity_manager::program::HeliumEntityManager; +use helium_entity_manager::{ + cpi::accounts::IssueProgramEntityV0, cpi::issue_program_entity_v0, ProgramApprovalV0, +}; +use helium_entity_manager::{IssueProgramEntityArgsV0, KeySerialization, SharedMerkleV0}; +use helium_sub_daos::{DaoV0, SubDaoV0}; +use pyth_solana_receiver_sdk::price_update::{PriceUpdateV2, VerificationLevel}; + +#[cfg(feature = "devnet")] +pub const ENTITY_METADATA_URL: &str = "https://entities.nft.test-helium.com"; + +#[cfg(not(feature = "devnet"))] +pub const ENTITY_METADATA_URL: &str = "https://entities.nft.helium.io"; + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)] +pub struct InitializeOrganizationArgsV0 { + pub oui: u64, + // Default escrow key is OUI_. For legacy OUIs, this can be overridden + pub escrow_key_override: Option, +} + +#[derive(Accounts)] +#[instruction(args: InitializeOrganizationArgsV0)] +pub struct InitializeOrganizationV0<'info> { + #[account(mut)] + pub payer: Signer<'info>, + #[account( + seeds = ["program_approval".as_bytes(), dao.key().as_ref(), crate::id().as_ref()], + seeds::program = helium_entity_manager_program.key(), + bump = program_approval.bump_seed, + )] + pub program_approval: Box>, + #[account( + has_one = collection, + has_one = sub_dao, + has_one = iot_mint, + has_one = iot_price_oracle, + )] + pub routing_manager: Box>, + #[account( + has_one = routing_manager, + )] + pub net_id: Box>, + #[account(mut)] + pub iot_mint: Box>, + #[account( + mut, + associated_token::mint = iot_mint, + associated_token::authority = payer, + )] + pub payer_iot_account: Box>, + #[account( + constraint = iot_price_oracle.verification_level == VerificationLevel::Full @ ErrorCode::PythPriceFeedStale, + )] + pub iot_price_oracle: Box>, + /// CHECK: The new authority for this OUI + pub authority: AccountInfo<'info>, + #[account( + init, + payer = payer, + seeds = ["organization".as_bytes(), routing_manager.key().as_ref(), &args.oui.to_le_bytes()[..]], + space = 8 + std::mem::size_of::() + args.escrow_key_override.map(|k| k.len()).unwrap_or(8) + 60, + bump + )] + pub organization: Box>, + pub collection: Box>, + /// CHECK: Handled by cpi + #[account( + mut, + seeds = ["metadata".as_bytes(), token_metadata_program.key().as_ref(), collection.key().as_ref()], + seeds::program = token_metadata_program.key(), + bump, + )] + pub collection_metadata: UncheckedAccount<'info>, + /// CHECK: Handled By cpi account + #[account( + seeds = ["metadata".as_bytes(), token_metadata_program.key().as_ref(), collection.key().as_ref(), "edition".as_bytes()], + seeds::program = token_metadata_program.key(), + bump, + )] + pub collection_master_edition: UncheckedAccount<'info>, + /// CHECK: Checked in cpi + #[account( + seeds = [b"entity_creator", dao.key().as_ref()], + seeds::program = helium_entity_manager_program.key(), + bump, + )] + pub entity_creator: UncheckedAccount<'info>, + pub dao: Box>, + #[account( + has_one = dao + )] + pub sub_dao: Box>, + #[account( + mut, + seeds = [ + "key_to_asset".as_bytes(), + dao.key().as_ref(), + &hash(format!("OUI_{}", args.oui).as_bytes()).to_bytes() + ], + seeds::program = helium_entity_manager_program.key(), + bump + )] + /// CHECK: Checked in cpi + pub key_to_asset: UncheckedAccount<'info>, + #[account( + mut, + seeds = [merkle_tree.key().as_ref()], + seeds::program = bubblegum_program.key(), + bump, + )] + pub tree_authority: Box>, + /// CHECK: Used in cpi + pub recipient: AccountInfo<'info>, + /// CHECK: Used in cpi + #[account(mut)] + pub merkle_tree: AccountInfo<'info>, + #[account( + seeds = ["collection_cpi".as_bytes()], + seeds::program = bubblegum_program.key(), + bump, + )] + /// CHECK: Used in cpi + pub bubblegum_signer: UncheckedAccount<'info>, + #[account( + mut, + seeds = ["shared_merkle".as_bytes(), &[3]], + seeds::program = helium_entity_manager_program.key(), + bump = shared_merkle.bump_seed, + has_one = merkle_tree + )] + pub shared_merkle: Box>, + + /// CHECK: Verified by constraint + #[account(address = mpl_token_metadata::ID)] + pub token_metadata_program: AccountInfo<'info>, + pub log_wrapper: Program<'info, Noop>, + pub bubblegum_program: Program<'info, Bubblegum>, + pub compression_program: Program<'info, SplAccountCompression>, + pub system_program: Program<'info, System>, + pub helium_entity_manager_program: Program<'info, HeliumEntityManager>, + pub token_program: Program<'info, Token>, +} + +pub fn handler( + ctx: Context, + args: InitializeOrganizationArgsV0, +) -> Result<()> { + let seeds: &[&[&[u8]]] = &[ + routing_manager_seeds!(ctx.accounts.routing_manager), + net_id_seeds!(ctx.accounts.net_id), + ]; + let key = format!("OUI_{}", args.oui); + let escrow_key = args.escrow_key_override.unwrap_or(key.clone()); + + ctx.accounts.organization.set_inner(OrganizationV0 { + oui: args.oui, + routing_manager: ctx.accounts.routing_manager.key(), + authority: ctx.accounts.authority.key(), + escrow_key, + bump_seed: ctx.bumps["organization"], + net_id: ctx.accounts.net_id.key(), + approved: false, + }); + + let uri = format!( + "{}/v2/oui/{}", + ENTITY_METADATA_URL, + ctx.accounts.key_to_asset.key(), + ); + + issue_program_entity_v0( + CpiContext::new_with_signer( + ctx.accounts.helium_entity_manager_program.to_account_info(), + IssueProgramEntityV0 { + payer: ctx.accounts.payer.to_account_info(), + program_approver: ctx.accounts.net_id.to_account_info(), + program_approval: ctx.accounts.program_approval.to_account_info(), + collection_authority: ctx.accounts.routing_manager.to_account_info(), + collection: ctx.accounts.collection.to_account_info(), + collection_metadata: ctx.accounts.collection_metadata.to_account_info(), + collection_master_edition: ctx.accounts.collection_master_edition.to_account_info(), + entity_creator: ctx.accounts.entity_creator.to_account_info(), + dao: ctx.accounts.dao.to_account_info(), + key_to_asset: ctx.accounts.key_to_asset.to_account_info(), + tree_authority: ctx.accounts.tree_authority.to_account_info(), + recipient: ctx.accounts.recipient.to_account_info(), + merkle_tree: ctx.accounts.merkle_tree.to_account_info(), + bubblegum_signer: ctx.accounts.bubblegum_signer.to_account_info(), + token_metadata_program: ctx.accounts.token_metadata_program.to_account_info(), + log_wrapper: ctx.accounts.log_wrapper.to_account_info(), + bubblegum_program: ctx.accounts.bubblegum_program.to_account_info(), + compression_program: ctx.accounts.compression_program.to_account_info(), + system_program: ctx.accounts.system_program.to_account_info(), + shared_merkle: Some(ctx.accounts.shared_merkle.to_account_info()), + }, + seeds, + ), + IssueProgramEntityArgsV0 { + entity_key: key.as_bytes().to_vec(), + name: key, + symbol: String::from("OUI"), + approver_seeds: seeds[1].iter().map(|s| s.to_vec()).collect(), + key_serialization: KeySerialization::UTF8, + metadata_url: Some(uri), + }, + )?; + + let message = ctx.accounts.iot_price_oracle.price_message; + let current_time = Clock::get()?.unix_timestamp; + require_gte!( + message + .publish_time + .saturating_add(if TESTING { 6000000 } else { 10 * 60 }.into()), + current_time, + ErrorCode::PythPriceNotFound + ); + let iot_price = message.ema_price; + require_gt!(iot_price, 0); + + // Remove the confidence from the price to use the most conservative price + // https://docs.pyth.network/price-feeds/solana-price-feeds/best-practices#confidence-intervals + let iot_price_with_conf = iot_price + .checked_sub(i64::try_from(message.ema_conf.checked_mul(2).unwrap()).unwrap()) + .unwrap(); + // Exponent is a negative number, likely -8 + // Since the price is multiplied by an extra 10^8, and we're dividing by that price, need to also multiply + // by the exponent + let exponent_dec = 10_u64 + .checked_pow(u32::try_from(-message.exponent).unwrap()) + .ok_or_else(|| error!(ErrorCode::ArithmeticError))?; + + require_gt!(iot_price_with_conf, 0); + let iot_fee = ctx + .accounts + .routing_manager + .oui_price_usd + .checked_mul(exponent_dec) + .unwrap() + .checked_div(iot_price_with_conf.try_into().unwrap()) + .unwrap(); + if iot_fee > 0 && ctx.accounts.payer.key() != ADMIN_KEY { + burn( + CpiContext::new( + ctx.accounts.token_program.to_account_info(), + Burn { + mint: ctx.accounts.iot_mint.to_account_info(), + from: ctx.accounts.payer_iot_account.to_account_info(), + authority: ctx.accounts.payer.to_account_info(), + }, + ), + iot_fee, + )?; + } + + Ok(()) +} diff --git a/programs/iot-routing-manager/src/instructions/initialize_routing_manager_v0.rs b/programs/iot-routing-manager/src/instructions/initialize_routing_manager_v0.rs new file mode 100644 index 000000000..964820768 --- /dev/null +++ b/programs/iot-routing-manager/src/instructions/initialize_routing_manager_v0.rs @@ -0,0 +1,185 @@ +use crate::error::ErrorCode; +use crate::{routing_manager_seeds, state::*}; +use anchor_lang::prelude::*; +use anchor_spl::{ + associated_token::AssociatedToken, + token::{self, Mint, MintTo, Token, TokenAccount}, +}; +use helium_sub_daos::SubDaoV0; +use mpl_token_metadata::types::{CollectionDetails, DataV2}; +use pyth_solana_receiver_sdk::price_update::PriceUpdateV2; +use shared_utils::create_metadata_accounts_v3; +use shared_utils::token_metadata::{ + create_master_edition_v3, CreateMasterEditionV3, CreateMetadataAccountsV3, + Metadata as MetadataProgram, +}; + +// 500m MOBILE +pub const CARRIER_STAKE_AMOUNT: u64 = 500_000_000_000_000; + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)] +pub struct InitializeRoutingManagerArgsV0 { + pub metadata_url: String, + pub devaddr_price_usd: u64, + pub oui_price_usd: u64, +} + +#[derive(Accounts)] +#[instruction(args: InitializeRoutingManagerArgsV0)] +pub struct InitializeRoutingManagerV0<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub authority: Signer<'info>, + /// CHECK: Set on the struct + pub update_authority: UncheckedAccount<'info>, + /// CHECK: Set on the struct + pub net_id_authority: UncheckedAccount<'info>, + #[account( + init, + payer = payer, + space = 8 + 60 + IotRoutingManagerV0::INIT_SPACE, + seeds = ["routing_manager".as_bytes(), sub_dao.key().as_ref()], + bump, + )] + pub routing_manager: Box>, + #[account( + has_one = authority, + has_one = dnt_mint, + )] + pub sub_dao: Box>, + pub dnt_mint: Box>, + pub iot_price_oracle: Box>, + #[account( + init, + payer = payer, + mint::decimals = 0, + mint::authority = routing_manager, + mint::freeze_authority = routing_manager, + seeds = ["collection".as_bytes(), routing_manager.key().as_ref()], + bump + )] + pub collection: Box>, + /// CHECK: Handled by cpi + #[account( + mut, + seeds = ["metadata".as_bytes(), token_metadata_program.key().as_ref(), collection.key().as_ref()], + seeds::program = token_metadata_program.key(), + bump, + )] + pub metadata: UncheckedAccount<'info>, + /// CHECK: Handled by cpi + #[account( + mut, + seeds = ["metadata".as_bytes(), token_metadata_program.key().as_ref(), collection.key().as_ref(), "edition".as_bytes()], + seeds::program = token_metadata_program.key(), + bump, + )] + pub master_edition: UncheckedAccount<'info>, + #[account( + init_if_needed, + payer = payer, + associated_token::mint = collection, + associated_token::authority = routing_manager, + )] + pub token_account: Box>, + + pub token_metadata_program: Program<'info, MetadataProgram>, + pub associated_token_program: Program<'info, AssociatedToken>, + pub system_program: Program<'info, System>, + pub token_program: Program<'info, Token>, + pub rent: Sysvar<'info, Rent>, +} + +impl<'info> InitializeRoutingManagerV0<'info> { + fn mint_ctx(&self) -> CpiContext<'_, '_, '_, 'info, MintTo<'info>> { + let cpi_accounts = MintTo { + mint: self.collection.to_account_info(), + to: self.token_account.to_account_info(), + authority: self.routing_manager.to_account_info(), + }; + CpiContext::new(self.token_program.to_account_info(), cpi_accounts) + } +} + +#[allow(deprecated)] +pub fn handler( + ctx: Context, + args: InitializeRoutingManagerArgsV0, +) -> Result<()> { + require!( + args.metadata_url.len() <= 200, + ErrorCode::InvalidStringLength + ); + + ctx.accounts.routing_manager.set_inner(IotRoutingManagerV0 { + update_authority: ctx.accounts.update_authority.key(), + net_id_authority: ctx.accounts.net_id_authority.key(), + collection: ctx.accounts.collection.key(), + // Initialized via set_carrier_tree + bump_seed: ctx.bumps["routing_manager"], + iot_mint: ctx.accounts.dnt_mint.key(), + iot_price_oracle: ctx.accounts.iot_price_oracle.key(), + sub_dao: ctx.accounts.sub_dao.key(), + devaddr_price_usd: args.devaddr_price_usd, + oui_price_usd: args.oui_price_usd, + }); + + let signer_seeds: &[&[&[u8]]] = &[routing_manager_seeds!(ctx.accounts.routing_manager)]; + token::mint_to(ctx.accounts.mint_ctx().with_signer(signer_seeds), 1)?; + + create_metadata_accounts_v3( + CpiContext::new_with_signer( + ctx + .accounts + .token_metadata_program + .to_account_info() + .clone(), + CreateMetadataAccountsV3 { + metadata: ctx.accounts.metadata.to_account_info().clone(), + mint: ctx.accounts.collection.to_account_info().clone(), + mint_authority: ctx.accounts.routing_manager.to_account_info().clone(), + payer: ctx.accounts.payer.to_account_info().clone(), + update_authority: ctx.accounts.routing_manager.to_account_info().clone(), + system_program: ctx.accounts.system_program.to_account_info().clone(), + token_metadata_program: ctx.accounts.token_metadata_program.clone(), + }, + signer_seeds, + ), + DataV2 { + name: "IOT Routing Manager Collection".to_string(), + symbol: "RM".to_string(), + uri: args.metadata_url.clone(), + seller_fee_basis_points: 0, + creators: None, + collection: None, + uses: None, + }, + true, + Some(CollectionDetails::V1 { size: 0 }), + )?; + + create_master_edition_v3( + CpiContext::new_with_signer( + ctx + .accounts + .token_metadata_program + .to_account_info() + .clone(), + CreateMasterEditionV3 { + edition: ctx.accounts.master_edition.to_account_info().clone(), + mint: ctx.accounts.collection.to_account_info().clone(), + update_authority: ctx.accounts.routing_manager.to_account_info().clone(), + mint_authority: ctx.accounts.routing_manager.to_account_info().clone(), + metadata: ctx.accounts.metadata.to_account_info().clone(), + payer: ctx.accounts.payer.to_account_info().clone(), + token_program: ctx.accounts.token_program.to_account_info().clone(), + system_program: ctx.accounts.system_program.to_account_info().clone(), + token_metadata_program: ctx.accounts.token_metadata_program.clone(), + }, + signer_seeds, + ), + Some(0), + )?; + + Ok(()) +} diff --git a/programs/iot-routing-manager/src/instructions/mod.rs b/programs/iot-routing-manager/src/instructions/mod.rs new file mode 100644 index 000000000..3a48929b9 --- /dev/null +++ b/programs/iot-routing-manager/src/instructions/mod.rs @@ -0,0 +1,17 @@ +pub mod approve_organization_v0; +pub mod initialize_devaddr_constraint_v0; +pub mod initialize_net_id_v0; +pub mod initialize_organization_delegate_v0; +pub mod initialize_organization_v0; +pub mod initialize_routing_manager_v0; +pub mod remove_organization_delegate_v0; +pub mod update_organization_v0; + +pub use approve_organization_v0::*; +pub use initialize_devaddr_constraint_v0::*; +pub use initialize_net_id_v0::*; +pub use initialize_organization_delegate_v0::*; +pub use initialize_organization_v0::*; +pub use initialize_routing_manager_v0::*; +pub use remove_organization_delegate_v0::*; +pub use update_organization_v0::*; diff --git a/programs/iot-routing-manager/src/instructions/remove_organization_delegate_v0.rs b/programs/iot-routing-manager/src/instructions/remove_organization_delegate_v0.rs new file mode 100644 index 000000000..dcc3b0cb1 --- /dev/null +++ b/programs/iot-routing-manager/src/instructions/remove_organization_delegate_v0.rs @@ -0,0 +1,24 @@ +use anchor_lang::prelude::*; + +use crate::{OrganizationDelegateV0, OrganizationV0}; + +#[derive(Accounts)] +pub struct RemoveOrganizationDelegateV0<'info> { + /// CHECK: Can be any sol wallet + #[account(mut)] + pub rent_refund: AccountInfo<'info>, + pub authority: Signer<'info>, + #[account( + has_one = authority + )] + pub organization: Account<'info, OrganizationV0>, + #[account( + mut, + close = rent_refund, + )] + pub organization_delegate: Account<'info, OrganizationDelegateV0>, +} + +pub fn handler(_: Context) -> Result<()> { + Ok(()) +} diff --git a/programs/iot-routing-manager/src/instructions/update_organization_v0.rs b/programs/iot-routing-manager/src/instructions/update_organization_v0.rs new file mode 100644 index 000000000..65d0f1015 --- /dev/null +++ b/programs/iot-routing-manager/src/instructions/update_organization_v0.rs @@ -0,0 +1,25 @@ +use anchor_lang::prelude::*; + +use crate::OrganizationV0; + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)] +pub struct UpdateOrganizationArgsV0 { + new_authority: Option, +} + +#[derive(Accounts)] +pub struct UpdateOrganizationV0<'info> { + pub authority: Signer<'info>, + #[account( + mut, + has_one = authority + )] + pub organization: Account<'info, OrganizationV0>, +} + +pub fn handler(ctx: Context, args: UpdateOrganizationArgsV0) -> Result<()> { + if let Some(authority) = args.new_authority { + ctx.accounts.organization.authority = authority; + } + Ok(()) +} diff --git a/programs/iot-routing-manager/src/lib.rs b/programs/iot-routing-manager/src/lib.rs new file mode 100644 index 000000000..bfc8f39ae --- /dev/null +++ b/programs/iot-routing-manager/src/lib.rs @@ -0,0 +1,82 @@ +use anchor_lang::prelude::*; +#[cfg(not(feature = "no-entrypoint"))] +use {default_env::default_env, solana_security_txt::security_txt}; + +declare_id!("irtjLnjCMmyowq2m3KWqpuFB3M9gdNA9A4t4d6VWmzB"); + +pub mod error; +pub mod instructions; +pub mod state; + +pub use instructions::*; +pub use state::*; + +#[cfg(not(feature = "no-entrypoint"))] +security_txt! { + name: "IOT Routing Manager", + project_url: "http://helium.com", + contacts: "email:hello@helium.foundation", + policy: "https://github.com/helium/helium-program-library/tree/master/SECURITY.md", + + + // Optional Fields + preferred_languages: "en", + source_code: "https://github.com/helium/helium-program-library/tree/master/programs/iot-routing-manager", + source_revision: default_env!("GITHUB_SHA", ""), + source_release: default_env!("GITHUB_REF_NAME", ""), + auditors: "Sec3" +} + +#[program] +pub mod iot_routing_manager { + use super::*; + + pub fn initialize_devaddr_constraint_v0( + ctx: Context, + args: InitializeDevaddrConstraintArgsV0, + ) -> Result<()> { + initialize_devaddr_constraint_v0::handler(ctx, args) + } + + pub fn initialize_net_id_v0( + ctx: Context, + args: InitializeNetIdArgsV0, + ) -> Result<()> { + initialize_net_id_v0::handler(ctx, args) + } + + pub fn initialize_organization_v0( + ctx: Context, + args: InitializeOrganizationArgsV0, + ) -> Result<()> { + initialize_organization_v0::handler(ctx, args) + } + + pub fn initialize_routing_manager_v0( + ctx: Context, + args: InitializeRoutingManagerArgsV0, + ) -> Result<()> { + initialize_routing_manager_v0::handler(ctx, args) + } + + pub fn initialize_organization_delegate_v0( + ctx: Context, + ) -> Result<()> { + initialize_organization_delegate_v0::handler(ctx) + } + + pub fn remove_organization_delegate_v0(ctx: Context) -> Result<()> { + remove_organization_delegate_v0::handler(ctx) + } + + pub fn approve_organization_v0(ctx: Context) -> Result<()> { + approve_organization_v0::handler(ctx) + } + + pub fn update_organization_v0( + ctx: Context, + args: UpdateOrganizationArgsV0, + ) -> Result<()> { + update_organization_v0::handler(ctx, args) + } +} diff --git a/programs/iot-routing-manager/src/state.rs b/programs/iot-routing-manager/src/state.rs new file mode 100644 index 000000000..7433b6ece --- /dev/null +++ b/programs/iot-routing-manager/src/state.rs @@ -0,0 +1,104 @@ +use anchor_lang::prelude::*; + +#[account] +#[derive(Default, InitSpace)] +pub struct IotRoutingManagerV0 { + pub sub_dao: Pubkey, + pub iot_mint: Pubkey, + pub iot_price_oracle: Pubkey, + pub update_authority: Pubkey, + pub net_id_authority: Pubkey, + pub collection: Pubkey, // The metaplex collection to be issued for Rewardable Entities + // with 6 decimals of precision + pub devaddr_price_usd: u64, + pub oui_price_usd: u64, + pub bump_seed: u8, +} + +#[macro_export] +macro_rules! routing_manager_seeds { + ( $manager:expr ) => { + &[ + b"routing_manager".as_ref(), + $manager.sub_dao.as_ref(), + &[$manager.bump_seed], + ] + }; +} + +#[account] +#[derive(Default)] +pub struct OrganizationV0 { + pub routing_manager: Pubkey, + pub net_id: Pubkey, + pub authority: Pubkey, + pub oui: u64, + pub escrow_key: String, + pub approved: bool, + pub bump_seed: u8, +} + +#[macro_export] +macro_rules! organization_seeds { + ( $org:expr ) => { + &[ + b"organization".as_ref(), + $org.routing_manager.as_ref(), + &$org.oui.to_le_bytes()[..], + &[$org.bump_seed], + ] + }; +} + +#[account] +#[derive(Default, InitSpace)] +pub struct NetIdV0 { + pub routing_manager: Pubkey, + pub id: u64, + pub authority: Pubkey, + pub current_addr_offset: u64, + pub bump_seed: u8, +} + +#[macro_export] +macro_rules! net_id_seeds { + ( $net_id:expr ) => { + &[ + b"net_id".as_ref(), + $net_id.routing_manager.as_ref(), + &$net_id.id.to_le_bytes()[..], + &[$net_id.bump_seed], + ] + }; +} + +#[account] +#[derive(Default, InitSpace)] +pub struct DevAddrConstraintV0 { + pub routing_manager: Pubkey, + pub net_id: Pubkey, + pub organization: Pubkey, + pub start_addr: u64, + pub end_addr: u64, + pub bump_seed: u8, +} + +#[account] +#[derive(Default, InitSpace)] +pub struct OrganizationDelegateV0 { + pub organization: Pubkey, + pub delegate: Pubkey, + pub bump_seed: u8, +} + +#[macro_export] +macro_rules! organization_delegate_seeds { + ( $delegate:expr ) => { + &[ + b"organization_delegate".as_ref(), + $delegate.organization.as_ref(), + $delegate.delegate.as_ref(), + &[$delegate.bump_seed], + ] + }; +} diff --git a/programs/mobile-entity-manager/src/instructions/initialize_subscriber_v0.rs b/programs/mobile-entity-manager/src/instructions/initialize_subscriber_v0.rs index 810a1fdf7..7dc61e26f 100644 --- a/programs/mobile-entity-manager/src/instructions/initialize_subscriber_v0.rs +++ b/programs/mobile-entity-manager/src/instructions/initialize_subscriber_v0.rs @@ -138,6 +138,7 @@ pub fn handler( bubblegum_program: ctx.accounts.bubblegum_program.to_account_info(), compression_program: ctx.accounts.compression_program.to_account_info(), system_program: ctx.accounts.system_program.to_account_info(), + shared_merkle: None, }, seeds, ), diff --git a/programs/mobile-entity-manager/src/instructions/issue_carrier_nft_v0.rs b/programs/mobile-entity-manager/src/instructions/issue_carrier_nft_v0.rs index 8493bbb2c..48634c944 100644 --- a/programs/mobile-entity-manager/src/instructions/issue_carrier_nft_v0.rs +++ b/programs/mobile-entity-manager/src/instructions/issue_carrier_nft_v0.rs @@ -132,6 +132,7 @@ pub fn handler(ctx: Context, args: IssueCarrierNftArgsV0) -> bubblegum_program: ctx.accounts.bubblegum_program.to_account_info(), compression_program: ctx.accounts.compression_program.to_account_info(), system_program: ctx.accounts.system_program.to_account_info(), + shared_merkle: None, }, seeds, ), diff --git a/tests/helium-entity-manager.ts b/tests/helium-entity-manager.ts index 62abdc310..0d6b6e49e 100644 --- a/tests/helium-entity-manager.ts +++ b/tests/helium-entity-manager.ts @@ -3,7 +3,7 @@ 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 initHeliumSubDaos } from "@helium/helium-sub-daos-sdk"; -import { notEmittedKey, init as initBurn } from "@helium/no-emit-sdk"; +import { init as initBurn, notEmittedKey } from "@helium/no-emit-sdk"; import { Asset, AssetProof, @@ -15,7 +15,7 @@ import { toBN, } from "@helium/spl-utils"; import { AddGatewayV1 } from "@helium/transactions"; -import { getAssociatedTokenAddressSync, getAccount } from "@solana/spl-token"; +import { getAccount, getAssociatedTokenAddressSync } from "@solana/spl-token"; import { ComputeBudgetProgram, Keypair, @@ -35,18 +35,18 @@ import { } from "../packages/helium-entity-manager-sdk/src"; import { DataCredits } from "../target/types/data_credits"; import { HeliumEntityManager } from "../target/types/helium_entity_manager"; -import { NoEmit } from "../target/types/no_emit"; import { HeliumSubDaos } from "../target/types/helium_sub_daos"; +import { NoEmit } from "../target/types/no_emit"; import { initTestDao, initTestSubdao } from "./utils/daos"; import { DC_FEE, + MAKER_STAKING_FEE, ensureDCIdl, - ensureHSDIdl, ensureHEMIdl, + ensureHSDIdl, initTestDataCredits, initTestMaker, - initTestRewardableEntityConfig, - MAKER_STAKING_FEE, + initTestRewardableEntityConfig } from "./utils/fixtures"; // @ts-ignore import bs58 from "bs58"; @@ -56,6 +56,7 @@ import { helium } from "@helium/proto"; // @ts-ignore import axios from "axios"; +import { keyToAssetKey } from "@helium/helium-entity-manager-sdk"; import { MerkleTree, SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, @@ -65,7 +66,6 @@ import { BN } from "bn.js"; import chaiAsPromised from "chai-as-promised"; import { createMockCompression } from "./utils/compression"; import { loadKeypair } from "./utils/solana"; -import { keyToAssetKey } from "@helium/helium-entity-manager-sdk"; chai.use(chaiAsPromised); diff --git a/tests/iot-routing-manager.ts b/tests/iot-routing-manager.ts new file mode 100644 index 000000000..2798eb756 --- /dev/null +++ b/tests/iot-routing-manager.ts @@ -0,0 +1,276 @@ +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 initHeliumSubDaos } from "@helium/helium-sub-daos-sdk"; +import { + SystemProgram, + Keypair, + PublicKey, + ComputeBudgetProgram, +} from "@solana/web3.js"; +import chai from "chai"; +import { init as initIotRoutingManager } from "../packages/iot-routing-manager-sdk/src"; +import { init as initHeliumEntityManager, sharedMerkleKey } from "../packages/helium-entity-manager-sdk/src"; +import { DataCredits } from "../target/types/data_credits"; +import { HeliumSubDaos } from "../target/types/helium_sub_daos"; +import { IotRoutingManager } from "../target/types/iot_routing_manager"; +import { initTestDao, initTestSubdao } from "./utils/daos"; +import { + ensureIrmIdl, + ensureDCIdl, + ensureHSDIdl, + initTestDataCredits, + initSharedMerkle, + ensureHEMIdl, +} from "./utils/fixtures"; +const { expect } = chai; +import chaiAsPromised from "chai-as-promised"; +import { getAccount } from "@solana/spl-token"; +import { random } from "./utils/string"; +import { + SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, + getConcurrentMerkleTreeAccountSize, +} from "@solana/spl-account-compression"; +import { HeliumEntityManager } from "../target/types/helium_entity_manager"; +import { IOT_PRICE_FEED } from "@helium/spl-utils"; + +chai.use(chaiAsPromised); + +describe("iot-routing-manager", () => { + anchor.setProvider(anchor.AnchorProvider.local("http://127.0.0.1:8899")); + + let dcProgram: Program; + let hsdProgram: Program; + let hemProgram: Program; + let irmProgram: Program; + + const provider = anchor.getProvider() as anchor.AnchorProvider; + const me = provider.wallet.publicKey; + let dao: PublicKey; + let subDao: PublicKey; + let iotMint: PublicKey | undefined; + let dcMint: PublicKey; + let programApproval: PublicKey; + + beforeEach(async () => { + dcProgram = await initDataCredits( + provider, + anchor.workspace.DataCredits.programId, + anchor.workspace.DataCredits.idl + ); + + ensureDCIdl(dcProgram); + + hsdProgram = await initHeliumSubDaos( + provider, + anchor.workspace.HeliumSubDaos.programId, + anchor.workspace.HeliumSubDaos.idl + ); + + ensureHSDIdl(hsdProgram); + + hemProgram = await initHeliumEntityManager( + provider, + anchor.workspace.HeliumEntityManager.programId, + anchor.workspace.HeliumEntityManager.idl + ); + ensureHEMIdl(hemProgram); + + irmProgram = await initIotRoutingManager( + provider, + anchor.workspace.IotRoutingManager.programId, + anchor.workspace.IotRoutingManager.idl + ); + ensureIrmIdl(irmProgram); + + + const dataCredits = await initTestDataCredits(dcProgram, provider); + dcMint = dataCredits.dcMint; + ({ dao } = await initTestDao( + hsdProgram, + provider, + 100, + me, + dataCredits.dcMint + )); + ({ subDao, mint: iotMint } = await initTestSubdao({ + hsdProgram, + provider, + authority: me, + dao, + numTokens: new anchor.BN("500000000000000"), + })); + + const approve = await hemProgram.methods + .approveProgramV0({ + programId: irmProgram.programId, + }) + .accounts({ dao }); + + programApproval = (await approve.pubkeys()).programApproval!; + await approve.rpc({ skipPreflight: true }); + + await initSharedMerkle(hemProgram); + }); + + it("should initialize a routing manager", async () => { + const { + pubkeys: { routingManager }, + } = await irmProgram.methods + .initializeRoutingManagerV0({ + metadataUrl: "https://some/url", + devaddrPriceUsd: new anchor.BN(100_000000), + ouiPriceUsd: new anchor.BN(100_000000), + }) + .preInstructions([ + ComputeBudgetProgram.setComputeUnitLimit({ units: 500000 }), + ]) + .accounts({ + updateAuthority: me, + netIdAuthority: me, + dntMint: iotMint, + subDao, + iotPriceOracle: IOT_PRICE_FEED, + }) + .rpcAndKeys({ skipPreflight: true }); + + const routingManagerAcc = await irmProgram.account.iotRoutingManagerV0.fetch(routingManager!); + + expect(routingManagerAcc.updateAuthority.toBase58()).to.eq(me.toBase58()); + expect(routingManagerAcc.netIdAuthority.toBase58()).to.eq(me.toBase58()); + }); + + describe("with a routing manager", async () => { + let routingManager: PublicKey; + + beforeEach(async () => { + const { + pubkeys: { routingManager: routingManagerK }, + } = await irmProgram.methods + .initializeRoutingManagerV0({ + metadataUrl: "https://some/url", + devaddrPriceUsd: new anchor.BN(100_000000), + ouiPriceUsd: new anchor.BN(100_000000), + }) + .preInstructions([ + ComputeBudgetProgram.setComputeUnitLimit({ units: 500000 }), + ]) + .accounts({ + updateAuthority: me, + netIdAuthority: me, + subDao, + iotPriceOracle: IOT_PRICE_FEED, + }) + .rpcAndKeys({ skipPreflight: true }); + routingManager = routingManagerK! + }); + + it("should initialize a net id", async () => { + const { + pubkeys: { netId }, + } = await irmProgram.methods + .initializeNetIdV0({ + netId: new anchor.BN(1), + }) + .accounts({ + authority: me, + routingManager, + }) + .rpcAndKeys({ skipPreflight: true }); + + const netIdAcc = await irmProgram.account.netIdV0.fetch(netId!); + expect(netIdAcc.authority.toBase58()).to.eq(me.toBase58()); + expect(netIdAcc.id.toNumber()).to.eq(1); + }) + + describe("with net id", async () => { + let netId: PublicKey; + beforeEach(async () => { + const { + pubkeys: { netId: netIdK }, + } = await irmProgram.methods + .initializeNetIdV0({ + netId: new anchor.BN(1), + }) + .accounts({ + authority: me, + routingManager, + }) + .rpcAndKeys({ skipPreflight: true }); + netId = netIdK!; + }); + + it ("should initialize an organization", async () => { + const { + pubkeys: { organization }, + } = await irmProgram.methods + .initializeOrganizationV0({ + oui: new anchor.BN(2), + escrowKeyOverride: null, + }) + .preInstructions( + [ComputeBudgetProgram.setComputeUnitLimit({ units: 500000 })] + ) + .accounts({ + authority: me, + netId, + }) + .rpcAndKeys({ skipPreflight: true }); + + const organizationAcc = await irmProgram.account.organizationV0.fetch(organization!); + expect(organizationAcc.authority.toBase58()).to.eq(me.toBase58()); + expect(organizationAcc.oui.toNumber()).to.eq(2); + expect(organizationAcc.escrowKey.toString()).to.eq("OUI_2"); + expect(organizationAcc.netId.toBase58()).to.eq(netId.toBase58()); + expect(organizationAcc.routingManager.toBase58()).to.eq(routingManager.toBase58()); + }) + + describe("with an organization", () => { + let organization: PublicKey; + beforeEach(async () => { + const { + pubkeys: { organization: organizationK }, + } = await irmProgram.methods + .initializeOrganizationV0({ + oui: new anchor.BN(2), + escrowKeyOverride: null, + }) + .preInstructions([ + ComputeBudgetProgram.setComputeUnitLimit({ units: 500000 }), + ]) + .accounts({ + authority: me, + netId, + }) + .rpcAndKeys({ skipPreflight: true }); + + organization = organizationK!; + + await irmProgram.methods + .approveOrganizationV0() + .accounts({ + organization, + }) + .rpc({ skipPreflight: true }); + }); + + it("should initialize a devaddr constraint", async () => { + const { + pubkeys: { devaddrConstraint }, + } = await irmProgram.methods + .initializeDevaddrConstraintV0({ + startAddr: null, + numBlocks: 2, + }) + .accounts({ + organization, + }) + .rpcAndKeys({ skipPreflight: true }); + const devaddr = await irmProgram.account.devAddrConstraintV0.fetch(devaddrConstraint!); + expect(devaddr.startAddr.toNumber()).to.eq(0); + expect(devaddr.endAddr.toNumber()).to.eq(16); + }); + }) + }) + }); +}); diff --git a/tests/mobile-entity-manager.ts b/tests/mobile-entity-manager.ts index e637517c7..229a82d67 100644 --- a/tests/mobile-entity-manager.ts +++ b/tests/mobile-entity-manager.ts @@ -20,6 +20,7 @@ import { ensureDCIdl, ensureHSDIdl, initTestDataCredits, + initSharedMerkle, } from './utils/fixtures'; const { expect } = chai; import chaiAsPromised from 'chai-as-promised'; diff --git a/tests/utils/fixtures.ts b/tests/utils/fixtures.ts index c07892246..9f95cd5dd 100644 --- a/tests/utils/fixtures.ts +++ b/tests/utils/fixtures.ts @@ -16,13 +16,14 @@ import { import { Keypair, PublicKey, SystemProgram } from "@solana/web3.js"; import { execSync } from "child_process"; import { ThresholdType } from "../../packages/circuit-breaker-sdk/src"; -import { makerKey } from "../../packages/helium-entity-manager-sdk/src"; +import { makerKey, sharedMerkleKey } from "../../packages/helium-entity-manager-sdk/src"; import { DataCredits } from "../../target/types/data_credits"; import { HeliumEntityManager } from "../../target/types/helium_entity_manager"; import { HeliumSubDaos } from "../../target/types/helium_sub_daos"; import { LazyDistributor } from "../../target/types/lazy_distributor"; import { initTestDao, initTestSubdao } from "./daos"; import { random } from "./string"; +import { IotRoutingManager } from "../../target/types/iot_routing_manager"; // TODO: replace this with helium default uri once uploaded const DEFAULT_METADATA_URL = @@ -115,6 +116,37 @@ export const initTestRewardableEntityConfig = async ( }; }; +export const initSharedMerkle = async (program: Program) => { + const sharedMerkle = sharedMerkleKey(3)[0]; + const exists = !!(await program.provider.connection.getAccountInfo(sharedMerkle)); + if (exists) { + return sharedMerkle; + } + const merkle = Keypair.generate(); + const space = getConcurrentMerkleTreeAccountSize(20, 64, 17); + const createMerkle = SystemProgram.createAccount({ + fromPubkey: (program.provider as anchor.AnchorProvider).wallet.publicKey, + newAccountPubkey: merkle.publicKey, + lamports: await (program.provider as anchor.AnchorProvider).connection.getMinimumBalanceForRentExemption( + space + ), + space: space, + programId: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, + }); + await program.methods + .initializeSharedMerkleV0({ + proofSize: 3, + }) + .preInstructions([createMerkle]) + .signers([merkle]) + .accounts({ + merkleTree: merkle.publicKey, + }) + .rpc({ skipPreflight: true }); + + return sharedMerkle +}; + export const initTestMaker = async ( program: Program, provider: anchor.AnchorProvider, @@ -243,6 +275,20 @@ export async function ensureMemIdl(memProgram: Program) { } } +export async function ensureIrmIdl(irmProgram: Program) { + try { + execSync( + `${ANCHOR_PATH} idl init --filepath ${__dirname}/../../target/idl/iot_routing_manager.json ${irmProgram.programId}`, + { stdio: "inherit", shell: "/bin/bash" } + ); + } catch { + execSync( + `${ANCHOR_PATH} idl upgrade --filepath ${__dirname}/../../target/idl/iot_routing_manager.json ${irmProgram.programId}`, + { stdio: "inherit", shell: "/bin/bash" } + ); + } +} + export async function ensureLDIdl(ldProgram: Program) { try { execSync( diff --git a/tsconfig.json b/tsconfig.json index 4c1f31c15..ef6dcde7f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,6 +19,9 @@ { "path": "./packages/lazy-transactions-sdk" }, + { + "path": "./packages/iot-routing-manager-sdk" + }, { "path": "./packages/helium-react-hooks" }, diff --git a/yarn.lock b/yarn.lock index 25e4dede6..528b92110 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1073,6 +1073,22 @@ __metadata: languageName: node linkType: hard +"@helium/iot-routing-manager-sdk@workspace:packages/iot-routing-manager-sdk": + version: 0.0.0-use.local + resolution: "@helium/iot-routing-manager-sdk@workspace:packages/iot-routing-manager-sdk" + dependencies: + "@coral-xyz/anchor": ^0.28.0 + "@helium/anchor-resolvers": ^0.8.7 + "@helium/helium-entity-manager-sdk": ^0.8.7 + 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/lazy-distributor-sdk@^0.8.7, @helium/lazy-distributor-sdk@workspace:packages/lazy-distributor-sdk": version: 0.0.0-use.local resolution: "@helium/lazy-distributor-sdk@workspace:packages/lazy-distributor-sdk"