Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(#675): On chain ouis and devaddrs #676

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ fanout = "fanqeMu3fw8R4LwKNbahPtYXJsyLL6NXyfe2BqzhfB6"
mobile_entity_manager = "memMa1HG4odAFmUbGWfPwS1WWfK95k99F2YTkGvyxZr"
hexboosting = "hexbnKYoA2GercNNhHUCCfrTRWrHjT6ujKPXTa5NPqJ"
no_emit = "noEmmgLmQdk6DLiPV8CSwQv3qQDyGEhz9m5A4zhtByv"
iot_routing_manager = "irtjLnjCMmyowq2m3KWqpuFB3M9gdNA9A4t4d6VWmzB"

[workspace]
members = [
Expand All @@ -34,6 +35,7 @@ members = [
"programs/mobile-entity-manager",
"programs/hexboosting",
"programs/no-emit",
"programs/iot-routing-manager",
]

[registry]
Expand Down Expand Up @@ -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"
Expand Down
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/anchor-resolvers/src/heliumCommonResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
12 changes: 12 additions & 0 deletions packages/helium-entity-manager-sdk/src/pdas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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")],
Expand Down
10 changes: 9 additions & 1 deletion packages/helium-entity-manager-sdk/src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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",
Expand Down
4 changes: 4 additions & 0 deletions packages/helium-vote-service/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PGDATABASE=postgres
PGUSER=postgres
PGPASSWORD=postgres
SOLANA_URL=https://solana-rpc.web.test-helium.com?session-key=Pluto
47 changes: 47 additions & 0 deletions packages/iot-routing-manager-sdk/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
5 changes: 5 additions & 0 deletions packages/iot-routing-manager-sdk/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { PublicKey } from "@solana/web3.js";

export const PROGRAM_ID = new PublicKey(
"irtjLnjCMmyowq2m3KWqpuFB3M9gdNA9A4t4d6VWmzB"
);
29 changes: 29 additions & 0 deletions packages/iot-routing-manager-sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -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<Program<IotRoutingManager>> {
if (!idl) {
idl = await Program.fetchIdl(programId, provider);
}
const iotRoutingManager = new Program<IotRoutingManager>(
idl as IotRoutingManager,
programId,
provider,
undefined,
() => {
return lazyDistributorResolvers;
}
) as Program<IotRoutingManager>;
return iotRoutingManager;
}
72 changes: 72 additions & 0 deletions packages/iot-routing-manager-sdk/src/pdas.ts
Original file line number Diff line number Diff line change
@@ -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
);
}
86 changes: 86 additions & 0 deletions packages/iot-routing-manager-sdk/src/resolvers.ts
Original file line number Diff line number Diff line change
@@ -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)
}
7 changes: 7 additions & 0 deletions packages/iot-routing-manager-sdk/tsconfig.cjs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.cjs.json",
"include": ["src"],
"compilerOptions": {
"outDir": "lib/cjs"
}
}
8 changes: 8 additions & 0 deletions packages/iot-routing-manager-sdk/tsconfig.esm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.esm.json",
"include": ["src"],
"compilerOptions": {
"outDir": "lib/esm",
"declarationDir": "lib/types"
}
}
23 changes: 23 additions & 0 deletions packages/iot-routing-manager-sdk/tsconfig.json
Original file line number Diff line number Diff line change
@@ -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"
}
]
}
Loading
Loading