Skip to content

Commit 2f1b1cd

Browse files
Merge branch 'main' into no-log-kp
2 parents e33f292 + 78cef3f commit 2f1b1cd

20 files changed

+483
-1
lines changed

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ JUPITER_FEE_BPS=
66
FLASH_PRIVILEGE= referral | nft | none
77
FLEXLEND_API_KEY=
88
HELIUS_API_KEY=
9+
ALLORA_API_KEY=
10+
ALLORA_API_URL=
11+
ALLORA_NETWORK= testnet | mainnet

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,29 @@ const signature = await agent.voltrWithdrawStrategy(
508508
const asset = await agent.getAsset("41Y8C4oxk4zgJT1KXyQr35UhZcfsp5mP86Z2G7UUzojU")
509509
```
510510

511+
### Get a price inference from Allora
512+
513+
Get the price for a given token and timeframe from Allora's API
514+
515+
```typescript
516+
const sol5mPrice = await agent.getPriceInference("SOL", "5m");
517+
console.log("5m price inference of SOL/USD:", sol5mPrice);
518+
```
519+
520+
### List all topics from Allora
521+
522+
```typescript
523+
const topics = await agent.getAllTopics();
524+
console.log("Allora topics:", topics);
525+
```
526+
527+
### Get an inference for an specific topic from Allora
528+
529+
```typescript
530+
const inference = await agent.getInferenceByTopicId(42);
531+
console.log("Allora inference for topic 42:", inference);
532+
```
533+
511534
## Examples
512535

513536
### LangGraph Multi-Agent System

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"dependencies": {
3232
"@3land/listings-sdk": "^0.0.7",
3333
"@ai-sdk/openai": "^1.0.11",
34+
"@alloralabs/allora-sdk": "^0.1.0",
3435
"@bonfida/spl-name-service": "^3.0.7",
3536
"@cks-systems/manifest-sdk": "0.1.59",
3637
"@coral-xyz/anchor": "0.29",

pnpm-lock.yaml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/actions/allora/getAllTopics.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Action } from "../../types/action";
2+
import { SolanaAgentKit } from "../../agent";
3+
import { z } from "zod";
4+
import { getAllTopics } from "../../tools";
5+
6+
const getAllTopicsAction: Action = {
7+
name: "ALLORA_GET_ALL_TOPICS",
8+
similes: [
9+
"get all topics",
10+
"get all inference topics",
11+
"get allora topics",
12+
"get all allora topics",
13+
"get allora inference topics",
14+
"get all allora inference topics",
15+
],
16+
description: "Get all topics from Allora's API",
17+
examples: [
18+
[
19+
{
20+
input: {},
21+
output: {
22+
status: "success",
23+
message: "Topics fetched successfully",
24+
topics:
25+
'[{"topic_id":5,"topic_name":"SOL 10min Prediction","description":null,"epoch_length":120,"ground_truth_lag":120,"loss_method":"mse","worker_submission_window":12,"worker_count":26859,"reputer_count":2735,"total_staked_allo":1.0200000004892,"total_emissions_allo":12.610109325686093,"is_active":true,"is_endorsed":false,"forge_competition_id":null,"forge_competition_start_date":null,"forge_competition_end_date":null,"updated_at":"2025-01-21T17:21:21.321Z"}]',
26+
},
27+
explanation: "Get all topics from Allora's API",
28+
},
29+
],
30+
],
31+
schema: z.object({}),
32+
handler: async (agent: SolanaAgentKit) => {
33+
const topics = await getAllTopics(agent);
34+
return {
35+
status: "success",
36+
message: "Topics fetched successfully",
37+
topics: topics,
38+
};
39+
},
40+
};
41+
42+
export default getAllTopicsAction;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { Action } from "../../types/action";
2+
import { SolanaAgentKit } from "../../agent";
3+
import { z } from "zod";
4+
import { getInferenceByTopicId } from "../../tools";
5+
6+
const getInferenceByTopicIdAction: Action = {
7+
name: "ALLORA_GET_INFERENCE_BY_TOPIC_ID",
8+
similes: ["get allora inference for topic 42", "get inference for topic 42"],
9+
description: "Get the inference for a given topic ID from Allora's API",
10+
examples: [
11+
[
12+
{
13+
input: {
14+
topicId: "42",
15+
},
16+
output: {
17+
status: "success",
18+
message: "Inference fetched successfully",
19+
inference: "The inference for topic 42 is 100",
20+
},
21+
explanation: "Get the inference for topic 42",
22+
},
23+
],
24+
],
25+
schema: z.object({
26+
topicId: z
27+
.string()
28+
.min(1)
29+
.describe("The topic ID to get the inference for"),
30+
}),
31+
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
32+
try {
33+
const { topicId } = input;
34+
35+
const inference = await getInferenceByTopicId(agent, topicId);
36+
return {
37+
status: "success",
38+
message: "Inference fetched successfully",
39+
inference: `The inference for topic ${topicId} is ${inference}`,
40+
};
41+
} catch (error: any) {
42+
return {
43+
status: "error",
44+
message: `Failed to fetch inference from Allora: ${error.message}`,
45+
};
46+
}
47+
},
48+
};
49+
50+
export default getInferenceByTopicIdAction;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { Action } from "../../types/action";
2+
import { SolanaAgentKit } from "../../agent";
3+
import { z } from "zod";
4+
import { getPriceInference } from "../../tools";
5+
6+
const getPriceInferenceAction: Action = {
7+
name: "ALLORA_GET_PRICE_INFERENCE",
8+
similes: [
9+
"get price inference for SOL in 10m",
10+
"get price forecast for SOL in 10m",
11+
"get allora price inference for SOL in 10m",
12+
"get allora price forecast for SOL in 10m",
13+
],
14+
description:
15+
"Get the price inference for a given token and timeframe from Allora's API",
16+
examples: [
17+
[
18+
{
19+
input: {
20+
tokenSymbol: "SOL",
21+
timeframe: "10m",
22+
},
23+
output: {
24+
status: "success",
25+
message: "Price inference fetched successfully",
26+
priceInference:
27+
"The price of SOL is expected to be 100 in 10 minutes",
28+
},
29+
explanation:
30+
"Get the price inference for SOL/USD price feed for the next 10 minutes",
31+
},
32+
],
33+
],
34+
schema: z.object({
35+
tokenSymbol: z
36+
.string()
37+
.min(1)
38+
.describe("The token symbol to get the price inference for"),
39+
timeframe: z
40+
.string()
41+
.min(1)
42+
.describe("The timeframe to get the price inference for"),
43+
}),
44+
handler: async (agent: SolanaAgentKit, input: any) => {
45+
try {
46+
const { tokenSymbol, timeframe } = input;
47+
48+
const price = await getPriceInference(agent, tokenSymbol, timeframe);
49+
return {
50+
status: "success",
51+
message: "Price inference fetched successfully",
52+
priceInference: `The price of ${tokenSymbol} is expected to be ${price} in ${timeframe}`,
53+
};
54+
} catch (error: any) {
55+
return {
56+
status: "error",
57+
message: `Failed to fetch price inference from Allora: ${error.message}`,
58+
};
59+
}
60+
},
61+
};
62+
63+
export default getPriceInferenceAction;

src/actions/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ import getAssetAction from "./metaplex/getAsset";
7676
import getAssetsByAuthorityAction from "./metaplex/getAssetsByAuthority";
7777
import getAssetsByCreatorAction from "./metaplex/getAssetsByCreator";
7878
import getInfoAction from "./agent/get_info";
79-
79+
import getPriceInferenceAction from "./allora/getPriceInference";
80+
import getAllTopicsAction from "./allora/getAllTopics";
81+
import getInferenceByTopicIdAction from "./allora/getInferenceByTopicId";
8082
export const ACTIONS = {
8183
GET_INFO_ACTION: getInfoAction,
8284
WALLET_ADDRESS_ACTION: getWalletAddressAction,
@@ -158,6 +160,9 @@ export const ACTIONS = {
158160
GET_ASSET_ACTION: getAssetAction,
159161
GET_ASSETS_BY_AUTHORITY_ACTION: getAssetsByAuthorityAction,
160162
GET_ASSETS_BY_CREATOR_ACTION: getAssetsByCreatorAction,
163+
GET_PRICE_INFERENCE_ACTION: getPriceInferenceAction,
164+
GET_ALL_TOPICS_ACTION: getAllTopicsAction,
165+
GET_INFERENCE_BY_TOPIC_ID_ACTION: getInferenceByTopicIdAction,
161166
};
162167

163168
export type { Action, ActionExample, Handler } from "../types/action";

src/agent/index.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ import {
117117
get_asset,
118118
get_assets_by_authority,
119119
get_assets_by_creator,
120+
getPriceInference,
121+
getAllTopics,
122+
getInferenceByTopicId,
120123
} from "../tools";
121124
import {
122125
Config,
@@ -141,6 +144,7 @@ import {
141144
GetAssetsByCreatorRpcInput,
142145
SearchAssetsRpcInput,
143146
} from "@metaplex-foundation/digital-asset-standard-api";
147+
import { AlloraInference, AlloraTopic } from "@alloralabs/allora-sdk";
144148

145149
/**
146150
* Main class for interacting with Solana blockchain
@@ -1029,4 +1033,16 @@ export class SolanaAgentKit {
10291033
): Promise<DasApiAssetList> {
10301034
return get_assets_by_creator(this, params);
10311035
}
1036+
async getPriceInference(
1037+
tokenSymbol: string,
1038+
timeframe: string,
1039+
): Promise<string> {
1040+
return getPriceInference(this, tokenSymbol, timeframe);
1041+
}
1042+
async getAllTopics(): Promise<AlloraTopic[]> {
1043+
return getAllTopics(this);
1044+
}
1045+
async getInferenceByTopicId(topicId: number): Promise<AlloraInference> {
1046+
return getInferenceByTopicId(this, topicId);
1047+
}
10321048
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Tool } from "langchain/tools";
2+
import { SolanaAgentKit } from "../../agent";
3+
import { AlloraGetAllTopicsResponse } from "../../index";
4+
5+
export class SolanaAlloraGetAllTopics extends Tool {
6+
name = "solana_allora_get_all_topics";
7+
description = `Get all topics from Allora's API
8+
9+
Inputs: None`;
10+
11+
constructor(private solanaKit: SolanaAgentKit) {
12+
super();
13+
}
14+
15+
async _call(_: string): Promise<string> {
16+
try {
17+
const topics = await this.solanaKit.getAllTopics();
18+
19+
const response: AlloraGetAllTopicsResponse = {
20+
status: "success",
21+
message: "Topics fetched successfully",
22+
topics,
23+
};
24+
25+
return JSON.stringify(response);
26+
} catch (error: any) {
27+
const response: AlloraGetAllTopicsResponse = {
28+
status: "error",
29+
message: error.message,
30+
code: error.code || "UNKNOWN_ERROR",
31+
};
32+
return JSON.stringify(response);
33+
}
34+
}
35+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Tool } from "langchain/tools";
2+
import { SolanaAgentKit } from "../../agent";
3+
import { AlloraGetInferenceByTopicIdResponse } from "../../types";
4+
5+
export class SolanaAlloraGetInferenceByTopicId extends Tool {
6+
name = "solana_allora_get_inference_by_topic_id";
7+
description = `Get the inference for a given topic ID from Allora's API
8+
Inputs:
9+
topicId: number as a string, e.g., "42"`;
10+
11+
constructor(private solanaKit: SolanaAgentKit) {
12+
super();
13+
}
14+
15+
async _call(input: string): Promise<string> {
16+
try {
17+
const topicId = Number(input);
18+
19+
const inference = await this.solanaKit.getInferenceByTopicId(topicId);
20+
21+
const response: AlloraGetInferenceByTopicIdResponse = {
22+
status: "success",
23+
message: "Inference fetched successfully",
24+
topicId,
25+
inference,
26+
};
27+
28+
return JSON.stringify(response);
29+
} catch (error: any) {
30+
const response: AlloraGetInferenceByTopicIdResponse = {
31+
status: "error",
32+
message: error.message,
33+
code: error.code || "UNKNOWN_ERROR",
34+
};
35+
return JSON.stringify(response);
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)