@svsprotocol/solana 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/LICENSE +158 -0
  2. package/README.md +365 -0
  3. package/dist/action-production-proof-evidence.js +553 -0
  4. package/dist/adapter-catalog.d.ts +29 -0
  5. package/dist/adapter-catalog.js +146 -0
  6. package/dist/adapter-core.d.ts +48 -0
  7. package/dist/adapter-core.js +249 -0
  8. package/dist/approval-signature.js +197 -0
  9. package/dist/base58.js +69 -0
  10. package/dist/bot-auth.js +50 -0
  11. package/dist/bot-certification-evidence.js +342 -0
  12. package/dist/bot-first-action-runbook.js +299 -0
  13. package/dist/bot-integration-contract.js +41 -0
  14. package/dist/certified-submit-status.js +176 -0
  15. package/dist/common.d.ts +1135 -0
  16. package/dist/elizaos.d.ts +43 -0
  17. package/dist/elizaos.js +227 -0
  18. package/dist/goat.d.ts +47 -0
  19. package/dist/goat.js +261 -0
  20. package/dist/index.d.ts +330 -0
  21. package/dist/index.js +128 -0
  22. package/dist/protocol.d.ts +205 -0
  23. package/dist/protocol.js +900 -0
  24. package/dist/receipt.js +51 -0
  25. package/dist/signed-proof-read-protection.js +495 -0
  26. package/dist/solana-agent-kit.d.ts +35 -0
  27. package/dist/solana-agent-kit.js +151 -0
  28. package/dist/svs-client.js +1232 -0
  29. package/dist/vercel-ai.d.ts +47 -0
  30. package/dist/vercel-ai.js +266 -0
  31. package/dist/verified-agent-adoption-kit.js +471 -0
  32. package/dist/verified-agent-profile.js +329 -0
  33. package/dist/verified-agent-registry-consumer.js +421 -0
  34. package/dist/verified-agent-registry.d.ts +36 -0
  35. package/dist/verified-agent-registry.js +826 -0
  36. package/dist/verified-agent-trust-score.js +335 -0
  37. package/dist/webhooks.js +834 -0
  38. package/package.json +72 -0
@@ -0,0 +1,43 @@
1
+ import type {
2
+ SvsAdapterActionInput,
3
+ SvsAdapterActionResult,
4
+ SvsAdapterOptions,
5
+ SvsAdapterReadinessResult,
6
+ JsonObject
7
+ } from "./common.js";
8
+ import { SvsAdapterCoreError } from "./adapter-core.js";
9
+
10
+ export const ELIZAOS_ADAPTER_VERSION: "svs.elizaos-adapter.v1";
11
+ export const ELIZAOS_PLUGIN_NAME: "svs-solana-verification";
12
+ export const ELIZAOS_ACTION_NAME: "SVS_VERIFY_AND_SUBMIT_SOLANA_ACTION";
13
+
14
+ export class SvsElizaOsAdapterError extends SvsAdapterCoreError {}
15
+
16
+ export interface SvsElizaOsAction {
17
+ name: typeof ELIZAOS_ACTION_NAME;
18
+ client: unknown;
19
+ similes: string[];
20
+ description: string;
21
+ examples: unknown[];
22
+ validate(): Promise<boolean>;
23
+ handler(runtime: unknown, message: unknown, state: unknown, options?: Partial<SvsAdapterActionInput>, callback?: (response: JsonObject) => unknown): Promise<{
24
+ success: boolean;
25
+ text: string;
26
+ data: SvsAdapterActionResult | JsonObject;
27
+ }>;
28
+ }
29
+
30
+ export interface SvsElizaOsPlugin {
31
+ name: typeof ELIZAOS_PLUGIN_NAME;
32
+ description: string;
33
+ actions: SvsElizaOsAction[];
34
+ providers: unknown[];
35
+ evaluators: unknown[];
36
+ services: unknown[];
37
+ }
38
+
39
+ export function createSvsElizaOsPlugin(options: SvsAdapterOptions): SvsElizaOsPlugin;
40
+ export function createSvsElizaOsAction(options: SvsAdapterOptions): SvsElizaOsAction;
41
+ export function requireSvsElizaOsProductionReady(options: SvsAdapterOptions): Promise<SvsAdapterReadinessResult>;
42
+ export function verifyAndSubmitElizaOsSolanaAction(options: SvsAdapterOptions & SvsAdapterActionInput): Promise<SvsAdapterActionResult>;
43
+ export function normalizeElizaOsActionInput(options?: { message?: unknown; state?: unknown; options?: JsonObject }): Partial<SvsAdapterActionInput>;
@@ -0,0 +1,227 @@
1
+ import {
2
+ SvsAdapterCoreError,
3
+ createSvsAdapterClient,
4
+ requireSvsAdapterProductionReady,
5
+ verifyAndSubmitSvsAdapterSolanaAction
6
+ } from "./adapter-core.js";
7
+
8
+ export const ELIZAOS_ADAPTER_VERSION = "svs.elizaos-adapter.v1";
9
+ export const ELIZAOS_PLUGIN_NAME = "svs-solana-verification";
10
+ export const ELIZAOS_ACTION_NAME = "SVS_VERIFY_AND_SUBMIT_SOLANA_ACTION";
11
+
12
+ export class SvsElizaOsAdapterError extends SvsAdapterCoreError {
13
+ constructor(message, details = {}) {
14
+ super(message, details);
15
+ this.name = "SvsElizaOsAdapterError";
16
+ }
17
+ }
18
+
19
+ export function createSvsElizaOsPlugin(options = {}) {
20
+ const action = createSvsElizaOsAction(options);
21
+
22
+ return {
23
+ name: ELIZAOS_PLUGIN_NAME,
24
+ description: "SVS Agent Verification actions for human-approved Solana automation.",
25
+ actions: [action],
26
+ providers: [],
27
+ evaluators: [],
28
+ services: []
29
+ };
30
+ }
31
+
32
+ export function createSvsElizaOsAction({
33
+ client = null,
34
+ baseUrl,
35
+ apiKey,
36
+ requestSigningSecret,
37
+ expectedIntegrationContractHash,
38
+ botId,
39
+ policyId = null,
40
+ rpcUrl = null,
41
+ certificationStaleAfterMs = undefined,
42
+ requireCurrentIntegrationContract = true,
43
+ waitForProof = false,
44
+ waitAttempts = 12,
45
+ waitIntervalMs = 5000,
46
+ fetchProof = true,
47
+ checkReceiptRegistryChain = true,
48
+ requireReadinessOnSubmit = true
49
+ } = {}) {
50
+ if (!botId) {
51
+ throw new Error("botId is required.");
52
+ }
53
+
54
+ const svs = createSvsAdapterClient({
55
+ client,
56
+ baseUrl,
57
+ apiKey,
58
+ requestSigningSecret,
59
+ expectedIntegrationContractHash
60
+ });
61
+ const defaults = {
62
+ botId,
63
+ policyId,
64
+ rpcUrl,
65
+ certificationStaleAfterMs,
66
+ requireCurrentIntegrationContract,
67
+ waitForProof,
68
+ waitAttempts,
69
+ waitIntervalMs,
70
+ fetchProof,
71
+ checkReceiptRegistryChain,
72
+ requireReadinessOnSubmit
73
+ };
74
+
75
+ return {
76
+ name: ELIZAOS_ACTION_NAME,
77
+ client: svs,
78
+ similes: [
79
+ "VERIFY_SOLANA_ACTION",
80
+ "SUBMIT_SOLANA_ACTION_WITH_SVS",
81
+ "HUMAN_APPROVED_SOLANA_ACTION"
82
+ ],
83
+ description: "Use SVS to require bot readiness, production certification, human approval, policy checks, and portable proof before trusting a Solana action.",
84
+ examples: [
85
+ [
86
+ {
87
+ user: "{{user1}}",
88
+ content: {
89
+ text: "Submit this Solana transaction only if SVS can verify it."
90
+ }
91
+ },
92
+ {
93
+ user: "{{agent}}",
94
+ content: {
95
+ text: "I will submit it through SVS for human approval and proof-backed execution.",
96
+ action: ELIZAOS_ACTION_NAME
97
+ }
98
+ }
99
+ ]
100
+ ],
101
+ async validate() {
102
+ try {
103
+ await requireSvsElizaOsProductionReady({
104
+ client: svs,
105
+ ...defaults
106
+ });
107
+
108
+ return true;
109
+ } catch {
110
+ return false;
111
+ }
112
+ },
113
+ async handler(runtime, message, state, options = {}, callback) {
114
+ try {
115
+ const input = normalizeElizaOsActionInput({ message, state, options });
116
+ const result = await verifyAndSubmitElizaOsSolanaAction({
117
+ client: svs,
118
+ ...defaults,
119
+ ...omitUndefined(input)
120
+ });
121
+ const response = {
122
+ success: result.ok === true,
123
+ text: result.nextAction?.message ?? `SVS action ${result.status}.`,
124
+ data: result
125
+ };
126
+
127
+ if (typeof callback === "function") {
128
+ await callback({
129
+ text: response.text,
130
+ action: ELIZAOS_ACTION_NAME,
131
+ data: result
132
+ });
133
+ }
134
+
135
+ return response;
136
+ } catch (error) {
137
+ const response = {
138
+ success: false,
139
+ text: error.message,
140
+ data: {
141
+ version: "svs.elizaos-action-error.v1",
142
+ ok: false,
143
+ status: "failed",
144
+ error: error.message,
145
+ details: error.details ?? null
146
+ }
147
+ };
148
+
149
+ if (typeof callback === "function") {
150
+ await callback({
151
+ text: response.text,
152
+ action: ELIZAOS_ACTION_NAME,
153
+ data: response.data
154
+ });
155
+ }
156
+
157
+ return response;
158
+ }
159
+ }
160
+ };
161
+ }
162
+
163
+ export async function requireSvsElizaOsProductionReady({
164
+ ...options
165
+ } = {}) {
166
+ return requireSvsAdapterProductionReady({
167
+ ...options,
168
+ readinessVersion: "svs.elizaos-readiness.v1",
169
+ readyMessage: "SVS ElizaOS action readiness and production certification passed.",
170
+ adapterLabel: "ElizaOS adapter",
171
+ ErrorClass: SvsElizaOsAdapterError
172
+ });
173
+ }
174
+
175
+ export async function verifyAndSubmitElizaOsSolanaAction({
176
+ ...options
177
+ } = {}) {
178
+ return verifyAndSubmitSvsAdapterSolanaAction({
179
+ ...options,
180
+ adapterVersion: ELIZAOS_ADAPTER_VERSION,
181
+ agentFramework: "elizaos",
182
+ resultVersion: "svs.elizaos-action-result.v1",
183
+ readinessVersion: "svs.elizaos-readiness.v1",
184
+ readyMessage: "SVS ElizaOS action readiness and production certification passed.",
185
+ adapterLabel: "ElizaOS adapter",
186
+ ErrorClass: SvsElizaOsAdapterError
187
+ });
188
+ }
189
+
190
+ export function normalizeElizaOsActionInput({ message = null, state = null, options = {} } = {}) {
191
+ const content = message?.content ?? {};
192
+ const source = {
193
+ ...(options.source ?? {}),
194
+ elizaMessageId: message?.id ?? message?.uuid ?? null,
195
+ elizaRoomId: message?.roomId ?? message?.room_id ?? null,
196
+ elizaUserId: message?.userId ?? message?.user_id ?? null,
197
+ elizaStateId: state?.id ?? null
198
+ };
199
+
200
+ return {
201
+ requestId: options.requestId ?? content.requestId ?? content.idempotencyKey ?? null,
202
+ idempotencyKey: options.idempotencyKey ?? options.requestId ?? content.idempotencyKey ?? content.requestId ?? null,
203
+ intent: options.intent ?? content.intent ?? null,
204
+ serializedTransaction: options.serializedTransaction ??
205
+ options.transaction?.serializedTransaction ??
206
+ content.serializedTransaction ??
207
+ content.transaction?.serializedTransaction ??
208
+ null,
209
+ policyId: options.policyId ?? content.policyId ?? undefined,
210
+ rpcUrl: options.rpcUrl ?? content.rpcUrl ?? undefined,
211
+ simulation: options.simulation ?? content.simulation ?? null,
212
+ metadata: options.metadata ?? content.metadata ?? null,
213
+ waitForProof: options.waitForProof ?? content.waitForProof ?? undefined,
214
+ waitAttempts: options.waitAttempts ?? content.waitAttempts ?? undefined,
215
+ waitIntervalMs: options.waitIntervalMs ?? content.waitIntervalMs ?? undefined,
216
+ fetchProof: options.fetchProof ?? content.fetchProof ?? undefined,
217
+ checkReceiptRegistryChain: options.checkReceiptRegistryChain ?? content.checkReceiptRegistryChain ?? undefined,
218
+ requireReadinessOnSubmit: options.requireReadinessOnSubmit ?? content.requireReadinessOnSubmit ?? undefined,
219
+ source
220
+ };
221
+ }
222
+
223
+ function omitUndefined(value) {
224
+ return Object.fromEntries(
225
+ Object.entries(value ?? {}).filter(([, entryValue]) => entryValue !== undefined)
226
+ );
227
+ }
package/dist/goat.d.ts ADDED
@@ -0,0 +1,47 @@
1
+ import type {
2
+ SvsAdapterActionInput,
3
+ SvsAdapterActionResult,
4
+ SvsAdapterOptions,
5
+ SvsAdapterReadinessResult,
6
+ JsonObject
7
+ } from "./common.js";
8
+ import { SvsAdapterCoreError } from "./adapter-core.js";
9
+
10
+ export const GOAT_ADAPTER_VERSION: "svs.goat-adapter.v1";
11
+ export const GOAT_PLUGIN_NAME: "svs-solana-verification";
12
+ export const GOAT_TOOL_NAME: "svs_verify_and_submit_solana_action";
13
+
14
+ export class SvsGoatAdapterError extends SvsAdapterCoreError {}
15
+
16
+ export interface SvsGoatTool {
17
+ name: typeof GOAT_TOOL_NAME;
18
+ description: string;
19
+ parameters: unknown;
20
+ version?: typeof GOAT_ADAPTER_VERSION;
21
+ execute(parameters: SvsAdapterActionInput): Promise<SvsAdapterActionResult>;
22
+ handler?: (parameters: SvsAdapterActionInput) => Promise<SvsAdapterActionResult>;
23
+ }
24
+
25
+ export interface SvsGoatPlugin {
26
+ version: typeof GOAT_ADAPTER_VERSION;
27
+ name: typeof GOAT_PLUGIN_NAME;
28
+ description: string;
29
+ botId: string;
30
+ policyId: string | null;
31
+ rpcUrl: string | null;
32
+ client: unknown;
33
+ tool: SvsGoatTool | unknown;
34
+ tools: unknown[];
35
+ supportsChain(chain?: unknown): boolean;
36
+ requireSvsProductionReady(options?: Partial<SvsAdapterOptions>): Promise<SvsAdapterReadinessResult>;
37
+ verifyAndSubmitSolanaAction(input: SvsAdapterActionInput, options?: Partial<SvsAdapterOptions>): Promise<SvsAdapterActionResult>;
38
+ getTools(): unknown[];
39
+ }
40
+
41
+ export function createSvsGoatPlugin(options: SvsAdapterOptions & { createTool?: Function | null; z?: unknown }): SvsGoatPlugin;
42
+ export function createSvsGoatTool(options?: { client?: unknown; defaults?: Partial<SvsAdapterOptions>; createTool?: Function | null; z?: unknown }): SvsGoatTool | unknown;
43
+ export function createGoatToolMetadata(options?: { z?: unknown }): JsonObject;
44
+ export function createGoatToolParameters(options?: { z?: unknown }): unknown;
45
+ export function requireSvsGoatProductionReady(options: SvsAdapterOptions): Promise<SvsAdapterReadinessResult>;
46
+ export function verifyAndSubmitGoatSolanaAction(options: SvsAdapterOptions & SvsAdapterActionInput): Promise<SvsAdapterActionResult>;
47
+ export function supportsSolanaChain(chain?: unknown): boolean;
package/dist/goat.js ADDED
@@ -0,0 +1,261 @@
1
+ import {
2
+ SvsAdapterCoreError,
3
+ createSvsAdapterClient,
4
+ requireSvsAdapterProductionReady,
5
+ verifyAndSubmitSvsAdapterSolanaAction
6
+ } from "./adapter-core.js";
7
+
8
+ export const GOAT_ADAPTER_VERSION = "svs.goat-adapter.v1";
9
+ export const GOAT_PLUGIN_NAME = "svs-solana-verification";
10
+ export const GOAT_TOOL_NAME = "svs_verify_and_submit_solana_action";
11
+
12
+ export class SvsGoatAdapterError extends SvsAdapterCoreError {
13
+ constructor(message, details = {}) {
14
+ super(message, details);
15
+ this.name = "SvsGoatAdapterError";
16
+ }
17
+ }
18
+
19
+ export function createSvsGoatPlugin({
20
+ client = null,
21
+ baseUrl,
22
+ apiKey,
23
+ requestSigningSecret,
24
+ expectedIntegrationContractHash,
25
+ botId,
26
+ policyId = null,
27
+ rpcUrl = null,
28
+ certificationStaleAfterMs = undefined,
29
+ requireCurrentIntegrationContract = true,
30
+ waitForProof = false,
31
+ waitAttempts = 12,
32
+ waitIntervalMs = 5000,
33
+ fetchProof = true,
34
+ checkReceiptRegistryChain = true,
35
+ requireReadinessOnSubmit = true,
36
+ createTool = null,
37
+ z = null
38
+ } = {}) {
39
+ if (!botId) {
40
+ throw new Error("botId is required.");
41
+ }
42
+
43
+ const svs = createSvsAdapterClient({
44
+ client,
45
+ baseUrl,
46
+ apiKey,
47
+ requestSigningSecret,
48
+ expectedIntegrationContractHash
49
+ });
50
+ const defaults = {
51
+ botId,
52
+ policyId,
53
+ rpcUrl,
54
+ certificationStaleAfterMs,
55
+ requireCurrentIntegrationContract,
56
+ waitForProof,
57
+ waitAttempts,
58
+ waitIntervalMs,
59
+ fetchProof,
60
+ checkReceiptRegistryChain,
61
+ requireReadinessOnSubmit
62
+ };
63
+ const tool = createSvsGoatTool({
64
+ client: svs,
65
+ defaults,
66
+ createTool,
67
+ z
68
+ });
69
+
70
+ return {
71
+ version: GOAT_ADAPTER_VERSION,
72
+ name: GOAT_PLUGIN_NAME,
73
+ description: "SVS Agent Verification plugin for GOAT Solana agents.",
74
+ botId,
75
+ policyId,
76
+ rpcUrl,
77
+ client: svs,
78
+ tool,
79
+ tools: [tool],
80
+ supportsChain: supportsSolanaChain,
81
+ async requireSvsProductionReady(options = {}) {
82
+ return requireSvsGoatProductionReady({
83
+ client: svs,
84
+ ...defaults,
85
+ ...options
86
+ });
87
+ },
88
+ async verifyAndSubmitSolanaAction(input = {}, options = {}) {
89
+ return verifyAndSubmitGoatSolanaAction({
90
+ client: svs,
91
+ ...defaults,
92
+ ...input,
93
+ ...options
94
+ });
95
+ },
96
+ getTools() {
97
+ return [tool];
98
+ }
99
+ };
100
+ }
101
+
102
+ export function createSvsGoatTool({
103
+ client,
104
+ defaults = {},
105
+ createTool = null,
106
+ z = null
107
+ } = {}) {
108
+ const metadata = createGoatToolMetadata({ z });
109
+ const execute = async (parameters = {}) => verifyAndSubmitGoatSolanaAction({
110
+ client,
111
+ ...defaults,
112
+ ...parameters
113
+ });
114
+
115
+ if (typeof createTool === "function") {
116
+ return createTool(metadata, execute);
117
+ }
118
+
119
+ return {
120
+ ...metadata,
121
+ version: GOAT_ADAPTER_VERSION,
122
+ execute,
123
+ handler: execute
124
+ };
125
+ }
126
+
127
+ export function createGoatToolMetadata({ z = null } = {}) {
128
+ return {
129
+ name: GOAT_TOOL_NAME,
130
+ description: "Require SVS production readiness, then queue a Solana action for human approval and proof-backed execution.",
131
+ parameters: createGoatToolParameters({ z })
132
+ };
133
+ }
134
+
135
+ export function createGoatToolParameters({ z = null } = {}) {
136
+ if (z?.object && z?.string && z?.boolean && z?.number && z?.unknown) {
137
+ return z.object({
138
+ requestId: z.string().optional(),
139
+ idempotencyKey: z.string().optional(),
140
+ intent: z.unknown(),
141
+ policyId: z.string().optional(),
142
+ serializedTransaction: z.string(),
143
+ rpcUrl: z.string().optional(),
144
+ simulation: z.unknown().optional(),
145
+ metadata: z.unknown().optional(),
146
+ waitForProof: z.boolean().optional(),
147
+ waitAttempts: z.number().optional(),
148
+ waitIntervalMs: z.number().optional(),
149
+ fetchProof: z.boolean().optional(),
150
+ checkReceiptRegistryChain: z.boolean().optional()
151
+ });
152
+ }
153
+
154
+ return {
155
+ type: "object",
156
+ required: ["intent", "serializedTransaction"],
157
+ properties: {
158
+ requestId: {
159
+ type: "string",
160
+ description: "Stable idempotency key for this GOAT agent action."
161
+ },
162
+ idempotencyKey: {
163
+ type: "string",
164
+ description: "Optional idempotency override. Defaults to requestId."
165
+ },
166
+ intent: {
167
+ type: "object",
168
+ description: "Human-readable Solana action intent shown to the SVS operator."
169
+ },
170
+ policyId: {
171
+ type: "string",
172
+ description: "SVS policy id to enforce for this action."
173
+ },
174
+ serializedTransaction: {
175
+ type: "string",
176
+ description: "Serialized Solana transaction prepared by the GOAT agent."
177
+ },
178
+ rpcUrl: {
179
+ type: "string",
180
+ description: "Solana RPC URL used to simulate or verify the action."
181
+ },
182
+ simulation: {
183
+ type: "object",
184
+ description: "Optional Solana simulation result produced before submitting."
185
+ },
186
+ metadata: {
187
+ type: "object",
188
+ description: "Optional non-secret metadata to include in the approval record."
189
+ },
190
+ waitForProof: {
191
+ type: "boolean",
192
+ description: "Wait for the human/operator path to produce a production proof."
193
+ },
194
+ waitAttempts: {
195
+ type: "number",
196
+ description: "Maximum proof polling attempts."
197
+ },
198
+ waitIntervalMs: {
199
+ type: "number",
200
+ description: "Delay between proof polling attempts."
201
+ },
202
+ fetchProof: {
203
+ type: "boolean",
204
+ description: "Fetch the proof package after proof status becomes ready."
205
+ },
206
+ checkReceiptRegistryChain: {
207
+ type: "boolean",
208
+ description: "Ask SVS to independently check the custom registry proof on-chain."
209
+ }
210
+ }
211
+ };
212
+ }
213
+
214
+ export async function requireSvsGoatProductionReady({
215
+ ...options
216
+ } = {}) {
217
+ return requireSvsAdapterProductionReady({
218
+ ...options,
219
+ readinessVersion: "svs.goat-readiness.v1",
220
+ readyMessage: "SVS GOAT plugin readiness and production certification passed.",
221
+ adapterLabel: "GOAT adapter",
222
+ ErrorClass: SvsGoatAdapterError
223
+ });
224
+ }
225
+
226
+ export async function verifyAndSubmitGoatSolanaAction({
227
+ ...options
228
+ } = {}) {
229
+ return verifyAndSubmitSvsAdapterSolanaAction({
230
+ ...options,
231
+ adapterVersion: GOAT_ADAPTER_VERSION,
232
+ agentFramework: "goat",
233
+ resultVersion: "svs.goat-action-result.v1",
234
+ readinessVersion: "svs.goat-readiness.v1",
235
+ readyMessage: "SVS GOAT plugin readiness and production certification passed.",
236
+ adapterLabel: "GOAT adapter",
237
+ ErrorClass: SvsGoatAdapterError
238
+ });
239
+ }
240
+
241
+ export function supportsSolanaChain(chain = null) {
242
+ if (chain === null || chain === undefined) {
243
+ return true;
244
+ }
245
+
246
+ if (typeof chain === "string") {
247
+ return chain.toLowerCase().includes("solana");
248
+ }
249
+
250
+ const candidates = [
251
+ chain.type,
252
+ chain.namespace,
253
+ chain.chain,
254
+ chain.id,
255
+ chain.name,
256
+ chain.network,
257
+ chain.chainType
258
+ ].filter(Boolean).map((value) => String(value).toLowerCase());
259
+
260
+ return candidates.some((value) => value.includes("solana"));
261
+ }