@relai-fi/x402 0.5.27 → 0.5.29
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.
- package/README.md +112 -0
- package/dist/client.cjs +12 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +12 -1
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +15 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/management.cjs +47 -0
- package/dist/management.cjs.map +1 -1
- package/dist/management.d.cts +67 -1
- package/dist/management.d.ts +67 -1
- package/dist/management.js +47 -0
- package/dist/management.js.map +1 -1
- package/dist/react/index.cjs +14 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +14 -1
- package/dist/react/index.js.map +1 -1
- package/dist/server.cjs +11 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +3 -1
- package/dist/server.d.ts +3 -1
- package/dist/server.js +11 -1
- package/dist/server.js.map +1 -1
- package/dist/{types-BSCuAZJb.d.cts → types-Y9ni5XwY.d.cts} +1 -1
- package/dist/{types-BSCuAZJb.d.ts → types-Y9ni5XwY.d.ts} +1 -1
- package/package.json +1 -1
package/dist/management.cjs
CHANGED
|
@@ -94,6 +94,29 @@ function createManagementClient(config) {
|
|
|
94
94
|
}
|
|
95
95
|
return res.json();
|
|
96
96
|
}
|
|
97
|
+
async function bridgeReq(method, path, x402Client, body) {
|
|
98
|
+
const res = await x402Client.fetch(`${base}${path}`, {
|
|
99
|
+
method,
|
|
100
|
+
headers: { ...headers, "Content-Type": "application/json" },
|
|
101
|
+
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
102
|
+
});
|
|
103
|
+
if (!res.ok) {
|
|
104
|
+
const text = await res.text().catch(() => "");
|
|
105
|
+
let parsed = {};
|
|
106
|
+
try {
|
|
107
|
+
parsed = JSON.parse(text);
|
|
108
|
+
} catch {
|
|
109
|
+
}
|
|
110
|
+
if (res.status === 503 && parsed["reason"] === "insufficient_liquidity") {
|
|
111
|
+
const avail = parsed["available"];
|
|
112
|
+
throw new Error(
|
|
113
|
+
`Bridge temporarily unavailable \u2014 insufficient liquidity` + (avail != null ? ` (available: $${Number(avail).toFixed(2)} USDC)` : "")
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
throw new Error(`[relai-bridge] ${method} ${path} \u2192 ${res.status}: ${text}`);
|
|
117
|
+
}
|
|
118
|
+
return res.json();
|
|
119
|
+
}
|
|
97
120
|
return {
|
|
98
121
|
// ── APIs ──────────────────────────────────────────────────────────────
|
|
99
122
|
createApi(input) {
|
|
@@ -138,6 +161,30 @@ function createManagementClient(config) {
|
|
|
138
161
|
if (options.cursor) params.set("cursor", options.cursor);
|
|
139
162
|
const qs = params.toString() ? `?${params}` : "";
|
|
140
163
|
return req("GET", `/v1/apis/${apiId}/logs${qs}`);
|
|
164
|
+
},
|
|
165
|
+
// ── Bridge ──────────────────────────────────────────────────
|
|
166
|
+
getBridgeQuote(amount, from = "solana") {
|
|
167
|
+
const params = new URLSearchParams({ amount: String(amount), from });
|
|
168
|
+
return req("GET", `/v1/bridge/quote?${params}`);
|
|
169
|
+
},
|
|
170
|
+
getBridgeBalances() {
|
|
171
|
+
return req("GET", "/v1/bridge/balances");
|
|
172
|
+
},
|
|
173
|
+
async bridgeSolanaToSkale(amount, destinationWallet, x402Client) {
|
|
174
|
+
return bridgeReq(
|
|
175
|
+
"POST",
|
|
176
|
+
"/v1/bridge/solana-to-skale",
|
|
177
|
+
x402Client,
|
|
178
|
+
{ amount, destinationWallet }
|
|
179
|
+
);
|
|
180
|
+
},
|
|
181
|
+
async bridgeSkaleToSolana(amount, destinationWallet, x402Client) {
|
|
182
|
+
return bridgeReq(
|
|
183
|
+
"POST",
|
|
184
|
+
"/v1/bridge/skale-to-solana",
|
|
185
|
+
x402Client,
|
|
186
|
+
{ amount, destinationWallet }
|
|
187
|
+
);
|
|
141
188
|
}
|
|
142
189
|
};
|
|
143
190
|
}
|
package/dist/management.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/management.ts"],"sourcesContent":["// src/management.ts\n// RelAI Management API client — create and manage monetised APIs programmatically.\n// Docs: https://relai.fi/documentation/management-api\n\nconst RELAI_API_BASE = 'https://api.relai.fi';\nconst BOOTSTRAP_URL = `${RELAI_API_BASE}/mcp/management/bootstrap/agent`;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ManagementClientConfig {\n /** Service key (sk_live_...) for authenticating management API calls */\n serviceKey: string;\n /** Override base URL (default: https://api.relai.fi) */\n baseUrl?: string;\n}\n\nexport interface RelaiApi {\n apiId: string;\n name: string;\n description?: string;\n baseUrl: string;\n subdomain?: string | null;\n network: string;\n facilitator: string;\n x402Version: number;\n status: string;\n merchantWallet: string;\n solanaWallet?: string | null;\n /** EVM wallet for cross-chain payments. Only relevant when network is Solana. */\n evmCrossChainWallet?: string | null;\n websiteUrl?: string;\n logoUrl?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ApiEndpointInput {\n path: string;\n method: string;\n usdPrice: number;\n enabled?: boolean;\n}\n\nexport interface ApiEndpoint extends ApiEndpointInput {\n network: string;\n enabled: boolean;\n}\n\nexport interface CreateApiInput {\n name: string;\n baseUrl: string;\n merchantWallet: string;\n /** Solana wallet for cross-chain payments. Only relevant when network is EVM. */\n solanaWallet?: string;\n /** EVM wallet for cross-chain payments. Only relevant when network is Solana. */\n evmCrossChainWallet?: string;\n network: string;\n description?: string;\n websiteUrl?: string;\n logoUrl?: string;\n endpoints?: ApiEndpointInput[];\n}\n\nexport interface UpdateApiInput {\n name?: string;\n description?: string;\n baseUrl?: string;\n merchantWallet?: string;\n /** Solana wallet for cross-chain payments. Set to null to remove. */\n solanaWallet?: string | null;\n /** EVM wallet for cross-chain payments. Set to null to remove. */\n evmCrossChainWallet?: string | null;\n websiteUrl?: string;\n logoUrl?: string;\n}\n\nexport interface ApiStats {\n apiId: string;\n totalRequests: number;\n totalRevenue: number;\n currency: string;\n}\n\nexport interface ApiPayment {\n transaction: string;\n path: string;\n method: string;\n amount: number;\n currency: string;\n network: string;\n status: string;\n success: boolean;\n payer: string;\n createdAt: string;\n}\n\nexport interface ApiPaymentsResult {\n apiId: string;\n payments: ApiPayment[];\n nextCursor: string | null;\n}\n\nexport interface ApiLogItem {\n id: string;\n timestamp: string;\n method: string;\n path: string;\n status: string;\n cost: number;\n currency: string;\n duration: number;\n transaction: string;\n network: string;\n success: boolean;\n payer: string;\n}\n\nexport interface ApiLogsResult {\n items: ApiLogItem[];\n nextCursor: string | null;\n}\n\nexport interface AgentBootstrapResult {\n key: string;\n label: string;\n active: boolean;\n createdAt: string;\n}\n\n// ============================================================================\n// Agent bootstrap (autonomous key provisioning)\n// ============================================================================\n\n/**\n * Bootstrap a service key for a Solana agent.\n * Run once — store the returned key securely.\n *\n * @param keypair A Solana Keypair (from @solana/web3.js)\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeySolana(\n keypair: { publicKey: { toBase58(): string }; secretKey: Uint8Array },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const { sign } = await import('tweetnacl');\n\n const publicKey = keypair.publicKey.toBase58();\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2 — sign\n const msgBytes = new TextEncoder().encode(message);\n const sigBytes = sign.detached(msgBytes, keypair.secretKey);\n const signature = Buffer.from(sigBytes).toString('base64');\n\n // Step 3 — get service key\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n/**\n * Bootstrap a service key for an EVM agent.\n * Run once — store the returned key securely.\n *\n * @param wallet An ethers.js Wallet or Signer with address + signMessage\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeyEvm(\n wallet: { address: string; signMessage(message: string): Promise<string> },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const publicKey = wallet.address;\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2+3 — sign and get key\n const signature = await wallet.signMessage(message);\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n// ============================================================================\n// Management client\n// ============================================================================\n\nexport interface RelaiManagementClient {\n // APIs\n createApi(input: CreateApiInput): Promise<RelaiApi>;\n listApis(): Promise<RelaiApi[]>;\n getApi(apiId: string): Promise<RelaiApi>;\n updateApi(apiId: string, input: UpdateApiInput): Promise<RelaiApi>;\n deleteApi(apiId: string): Promise<{ success: boolean; apiId: string }>;\n\n // Pricing\n getPricing(apiId: string): Promise<{ apiId: string; endpoints: ApiEndpoint[] }>;\n setPricing(apiId: string, endpoints: ApiEndpointInput[]): Promise<{ success: boolean; apiId: string; updated: number }>;\n\n // Analytics\n getStats(apiId: string): Promise<ApiStats>;\n getPayments(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiPaymentsResult>;\n getLogs(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiLogsResult>;\n}\n\n/**\n * Create a RelAI Management API client.\n *\n * @example\n * ```typescript\n * import { createManagementClient } from '@relai-fi/x402/management';\n *\n * const mgmt = createManagementClient({ serviceKey: process.env.RELAI_SERVICE_KEY! });\n *\n * const api = await mgmt.createApi({\n * name: 'My ML API',\n * baseUrl: 'https://inference.example.com',\n * merchantWallet: '0xYourWallet',\n * network: 'base',\n * endpoints: [{ path: '/v1/predict', method: 'post', usdPrice: 0.05 }],\n * });\n * ```\n */\nexport function createManagementClient(config: ManagementClientConfig): RelaiManagementClient {\n const base = (config.baseUrl ?? RELAI_API_BASE).replace(/\\/$/, '');\n const headers = {\n 'X-Service-Key': config.serviceKey,\n 'Content-Type': 'application/json',\n };\n\n async function req<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${base}${path}`, {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`[relai-mgmt] ${method} ${path} → ${res.status}: ${text}`);\n }\n return res.json() as Promise<T>;\n }\n\n return {\n // ── APIs ──────────────────────────────────────────────────────────────\n\n createApi(input) {\n return req<RelaiApi>('POST', '/v1/apis', input);\n },\n\n async listApis() {\n const data = await req<{ apis: RelaiApi[] }>('GET', '/v1/apis');\n return data.apis;\n },\n\n getApi(apiId) {\n return req<RelaiApi>('GET', `/v1/apis/${apiId}`);\n },\n\n updateApi(apiId, input) {\n return req<RelaiApi>('PATCH', `/v1/apis/${apiId}`, input);\n },\n\n deleteApi(apiId) {\n return req<{ success: boolean; apiId: string }>('DELETE', `/v1/apis/${apiId}`);\n },\n\n // ── Pricing ──────────────────────────────────────────────────────────\n\n getPricing(apiId) {\n return req<{ apiId: string; endpoints: ApiEndpoint[] }>('GET', `/v1/apis/${apiId}/pricing`);\n },\n\n setPricing(apiId, endpoints) {\n return req<{ success: boolean; apiId: string; updated: number }>('PUT', `/v1/apis/${apiId}/pricing`, { endpoints });\n },\n\n // ── Analytics ────────────────────────────────────────────────────────\n\n getStats(apiId) {\n return req<ApiStats>('GET', `/v1/apis/${apiId}/stats`);\n },\n\n getPayments(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiPaymentsResult>('GET', `/v1/apis/${apiId}/payments${qs}`);\n },\n\n getLogs(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiLogsResult>('GET', `/v1/apis/${apiId}/logs${qs}`);\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/management.ts"],"sourcesContent":["// src/management.ts\n// RelAI Management API client — create and manage monetised APIs programmatically.\n// Docs: https://relai.fi/documentation/management-api\n\nconst RELAI_API_BASE = 'https://api.relai.fi';\nconst BOOTSTRAP_URL = `${RELAI_API_BASE}/mcp/management/bootstrap/agent`;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ManagementClientConfig {\n /** Service key (sk_live_...) for authenticating management API calls */\n serviceKey: string;\n /** Override base URL (default: https://api.relai.fi) */\n baseUrl?: string;\n}\n\nexport interface RelaiApi {\n apiId: string;\n name: string;\n description?: string;\n baseUrl: string;\n subdomain?: string | null;\n network: string;\n facilitator: string;\n x402Version: number;\n status: string;\n merchantWallet: string;\n solanaWallet?: string | null;\n /** EVM wallet for cross-chain payments. Only relevant when network is Solana. */\n evmCrossChainWallet?: string | null;\n websiteUrl?: string;\n logoUrl?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ApiEndpointInput {\n path: string;\n method: string;\n usdPrice: number;\n enabled?: boolean;\n}\n\nexport interface ApiEndpoint extends ApiEndpointInput {\n network: string;\n enabled: boolean;\n}\n\nexport interface CreateApiInput {\n name: string;\n baseUrl: string;\n merchantWallet: string;\n /** Solana wallet for cross-chain payments. Only relevant when network is EVM. */\n solanaWallet?: string;\n /** EVM wallet for cross-chain payments. Only relevant when network is Solana. */\n evmCrossChainWallet?: string;\n network: string;\n description?: string;\n websiteUrl?: string;\n logoUrl?: string;\n endpoints?: ApiEndpointInput[];\n}\n\nexport interface UpdateApiInput {\n name?: string;\n description?: string;\n baseUrl?: string;\n merchantWallet?: string;\n /** Solana wallet for cross-chain payments. Set to null to remove. */\n solanaWallet?: string | null;\n /** EVM wallet for cross-chain payments. Set to null to remove. */\n evmCrossChainWallet?: string | null;\n websiteUrl?: string;\n logoUrl?: string;\n}\n\nexport interface ApiStats {\n apiId: string;\n totalRequests: number;\n totalRevenue: number;\n currency: string;\n}\n\nexport interface ApiPayment {\n transaction: string;\n path: string;\n method: string;\n amount: number;\n currency: string;\n network: string;\n status: string;\n success: boolean;\n payer: string;\n createdAt: string;\n}\n\nexport interface ApiPaymentsResult {\n apiId: string;\n payments: ApiPayment[];\n nextCursor: string | null;\n}\n\nexport interface ApiLogItem {\n id: string;\n timestamp: string;\n method: string;\n path: string;\n status: string;\n cost: number;\n currency: string;\n duration: number;\n transaction: string;\n network: string;\n success: boolean;\n payer: string;\n}\n\nexport interface ApiLogsResult {\n items: ApiLogItem[];\n nextCursor: string | null;\n}\n\n// ── Bridge types ─────────────────────────────────────────────────────────────\n\nexport interface BridgeQuoteResult {\n inputAmount: number;\n outputAmount: number;\n fee: number;\n feeBps: number;\n inputUsd: number;\n outputUsd: number;\n direction: 'solana-to-skale' | 'skale-to-solana';\n from: string;\n to: string;\n}\n\nexport interface BridgeBalances {\n solana: { atomic: number; usd: number };\n skaleBase: { atomic: number; usd: number };\n base: { atomic: number; usd: number };\n}\n\nexport interface BridgeResult {\n success: boolean;\n direction: 'solana-to-skale' | 'skale-to-solana';\n destinationWallet: string;\n amountOut: number;\n amountOutUsd: number;\n txHash: string;\n explorerUrl: string;\n}\n\nexport interface AgentBootstrapResult {\n key: string;\n label: string;\n active: boolean;\n createdAt: string;\n}\n\n// ============================================================================\n// Agent bootstrap (autonomous key provisioning)\n// ============================================================================\n\n/**\n * Bootstrap a service key for a Solana agent.\n * Run once — store the returned key securely.\n *\n * @param keypair A Solana Keypair (from @solana/web3.js)\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeySolana(\n keypair: { publicKey: { toBase58(): string }; secretKey: Uint8Array },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const { sign } = await import('tweetnacl');\n\n const publicKey = keypair.publicKey.toBase58();\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2 — sign\n const msgBytes = new TextEncoder().encode(message);\n const sigBytes = sign.detached(msgBytes, keypair.secretKey);\n const signature = Buffer.from(sigBytes).toString('base64');\n\n // Step 3 — get service key\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n/**\n * Bootstrap a service key for an EVM agent.\n * Run once — store the returned key securely.\n *\n * @param wallet An ethers.js Wallet or Signer with address + signMessage\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeyEvm(\n wallet: { address: string; signMessage(message: string): Promise<string> },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const publicKey = wallet.address;\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2+3 — sign and get key\n const signature = await wallet.signMessage(message);\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n// ============================================================================\n// Management client\n// ============================================================================\n\nexport interface RelaiManagementClient {\n // APIs\n createApi(input: CreateApiInput): Promise<RelaiApi>;\n listApis(): Promise<RelaiApi[]>;\n getApi(apiId: string): Promise<RelaiApi>;\n updateApi(apiId: string, input: UpdateApiInput): Promise<RelaiApi>;\n deleteApi(apiId: string): Promise<{ success: boolean; apiId: string }>;\n\n // Pricing\n getPricing(apiId: string): Promise<{ apiId: string; endpoints: ApiEndpoint[] }>;\n setPricing(apiId: string, endpoints: ApiEndpointInput[]): Promise<{ success: boolean; apiId: string; updated: number }>;\n\n // Analytics\n getStats(apiId: string): Promise<ApiStats>;\n getPayments(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiPaymentsResult>;\n getLogs(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiLogsResult>;\n\n // Bridge\n /**\n * Get a bridge quote — fee and net output for a given USD amount.\n * @param amount Amount in USD (e.g. 10.0)\n * @param from Source network: 'solana' | 'skale-base' (default: 'solana')\n */\n getBridgeQuote(amount: number, from?: 'solana' | 'skale-base'): Promise<BridgeQuoteResult>;\n\n /**\n * Get current USDC liquidity on all bridge networks.\n * Use this before bridging to confirm availability.\n */\n getBridgeBalances(): Promise<BridgeBalances>;\n\n /**\n * Bridge USDC from Solana to SKALE Base via x402 payment.\n * This call returns HTTP 402 — pass a createX402Client instance to handle payment automatically.\n *\n * @param amount Amount in USD\n * @param destinationWallet EVM address on SKALE Base\n * @param x402Client A configured createX402Client instance for Solana\n */\n bridgeSolanaToSkale(\n amount: number,\n destinationWallet: string,\n x402Client: { fetch(url: string, init?: RequestInit): Promise<Response> },\n ): Promise<BridgeResult>;\n\n /**\n * Bridge USDC from SKALE Base to Solana via x402 payment.\n *\n * @param amount Amount in USD\n * @param destinationWallet Solana public key (base58)\n * @param x402Client A configured createX402Client instance for EVM/SKALE Base\n */\n bridgeSkaleToSolana(\n amount: number,\n destinationWallet: string,\n x402Client: { fetch(url: string, init?: RequestInit): Promise<Response> },\n ): Promise<BridgeResult>;\n}\n\n/**\n * Create a RelAI Management API client.\n *\n * @example\n * ```typescript\n * import { createManagementClient } from '@relai-fi/x402/management';\n *\n * const mgmt = createManagementClient({ serviceKey: process.env.RELAI_SERVICE_KEY! });\n *\n * const api = await mgmt.createApi({\n * name: 'My ML API',\n * baseUrl: 'https://inference.example.com',\n * merchantWallet: '0xYourWallet',\n * network: 'base',\n * endpoints: [{ path: '/v1/predict', method: 'post', usdPrice: 0.05 }],\n * });\n * ```\n */\nexport function createManagementClient(config: ManagementClientConfig): RelaiManagementClient {\n const base = (config.baseUrl ?? RELAI_API_BASE).replace(/\\/$/, '');\n const headers = {\n 'X-Service-Key': config.serviceKey,\n 'Content-Type': 'application/json',\n };\n\n async function req<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${base}${path}`, {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`[relai-mgmt] ${method} ${path} → ${res.status}: ${text}`);\n }\n return res.json() as Promise<T>;\n }\n\n async function bridgeReq<T>(\n method: string,\n path: string,\n x402Client: { fetch(url: string, init?: RequestInit): Promise<Response> },\n body?: unknown,\n ): Promise<T> {\n const res = await x402Client.fetch(`${base}${path}`, {\n method,\n headers: { ...headers, 'Content-Type': 'application/json' },\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n let parsed: Record<string, unknown> = {};\n try { parsed = JSON.parse(text); } catch { /* ignore */ }\n if (res.status === 503 && parsed['reason'] === 'insufficient_liquidity') {\n const avail = parsed['available'] as number | undefined;\n throw new Error(\n `Bridge temporarily unavailable — insufficient liquidity` +\n (avail != null ? ` (available: $${Number(avail).toFixed(2)} USDC)` : ''),\n );\n }\n throw new Error(`[relai-bridge] ${method} ${path} → ${res.status}: ${text}`);\n }\n return res.json() as Promise<T>;\n }\n\n return {\n // ── APIs ──────────────────────────────────────────────────────────────\n\n createApi(input) {\n return req<RelaiApi>('POST', '/v1/apis', input);\n },\n\n async listApis() {\n const data = await req<{ apis: RelaiApi[] }>('GET', '/v1/apis');\n return data.apis;\n },\n\n getApi(apiId) {\n return req<RelaiApi>('GET', `/v1/apis/${apiId}`);\n },\n\n updateApi(apiId, input) {\n return req<RelaiApi>('PATCH', `/v1/apis/${apiId}`, input);\n },\n\n deleteApi(apiId) {\n return req<{ success: boolean; apiId: string }>('DELETE', `/v1/apis/${apiId}`);\n },\n\n // ── Pricing ──────────────────────────────────────────────────────────\n\n getPricing(apiId) {\n return req<{ apiId: string; endpoints: ApiEndpoint[] }>('GET', `/v1/apis/${apiId}/pricing`);\n },\n\n setPricing(apiId, endpoints) {\n return req<{ success: boolean; apiId: string; updated: number }>('PUT', `/v1/apis/${apiId}/pricing`, { endpoints });\n },\n\n // ── Analytics ────────────────────────────────────────────────────────\n\n getStats(apiId) {\n return req<ApiStats>('GET', `/v1/apis/${apiId}/stats`);\n },\n\n getPayments(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiPaymentsResult>('GET', `/v1/apis/${apiId}/payments${qs}`);\n },\n\n getLogs(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiLogsResult>('GET', `/v1/apis/${apiId}/logs${qs}`);\n },\n\n // ── Bridge ──────────────────────────────────────────────────\n\n getBridgeQuote(amount, from = 'solana') {\n const params = new URLSearchParams({ amount: String(amount), from });\n return req<BridgeQuoteResult>('GET', `/v1/bridge/quote?${params}`);\n },\n\n getBridgeBalances() {\n return req<BridgeBalances>('GET', '/v1/bridge/balances');\n },\n\n async bridgeSolanaToSkale(amount, destinationWallet, x402Client) {\n return bridgeReq<BridgeResult>(\n 'POST',\n '/v1/bridge/solana-to-skale',\n x402Client,\n { amount, destinationWallet },\n );\n },\n\n async bridgeSkaleToSolana(amount, destinationWallet, x402Client) {\n return bridgeReq<BridgeResult>(\n 'POST',\n '/v1/bridge/skale-to-solana',\n x402Client,\n { amount, destinationWallet },\n );\n },\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/management.d.cts
CHANGED
|
@@ -100,6 +100,40 @@ interface ApiLogsResult {
|
|
|
100
100
|
items: ApiLogItem[];
|
|
101
101
|
nextCursor: string | null;
|
|
102
102
|
}
|
|
103
|
+
interface BridgeQuoteResult {
|
|
104
|
+
inputAmount: number;
|
|
105
|
+
outputAmount: number;
|
|
106
|
+
fee: number;
|
|
107
|
+
feeBps: number;
|
|
108
|
+
inputUsd: number;
|
|
109
|
+
outputUsd: number;
|
|
110
|
+
direction: 'solana-to-skale' | 'skale-to-solana';
|
|
111
|
+
from: string;
|
|
112
|
+
to: string;
|
|
113
|
+
}
|
|
114
|
+
interface BridgeBalances {
|
|
115
|
+
solana: {
|
|
116
|
+
atomic: number;
|
|
117
|
+
usd: number;
|
|
118
|
+
};
|
|
119
|
+
skaleBase: {
|
|
120
|
+
atomic: number;
|
|
121
|
+
usd: number;
|
|
122
|
+
};
|
|
123
|
+
base: {
|
|
124
|
+
atomic: number;
|
|
125
|
+
usd: number;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
interface BridgeResult {
|
|
129
|
+
success: boolean;
|
|
130
|
+
direction: 'solana-to-skale' | 'skale-to-solana';
|
|
131
|
+
destinationWallet: string;
|
|
132
|
+
amountOut: number;
|
|
133
|
+
amountOutUsd: number;
|
|
134
|
+
txHash: string;
|
|
135
|
+
explorerUrl: string;
|
|
136
|
+
}
|
|
103
137
|
interface AgentBootstrapResult {
|
|
104
138
|
key: string;
|
|
105
139
|
label: string;
|
|
@@ -159,6 +193,38 @@ interface RelaiManagementClient {
|
|
|
159
193
|
from?: string;
|
|
160
194
|
cursor?: string;
|
|
161
195
|
}): Promise<ApiLogsResult>;
|
|
196
|
+
/**
|
|
197
|
+
* Get a bridge quote — fee and net output for a given USD amount.
|
|
198
|
+
* @param amount Amount in USD (e.g. 10.0)
|
|
199
|
+
* @param from Source network: 'solana' | 'skale-base' (default: 'solana')
|
|
200
|
+
*/
|
|
201
|
+
getBridgeQuote(amount: number, from?: 'solana' | 'skale-base'): Promise<BridgeQuoteResult>;
|
|
202
|
+
/**
|
|
203
|
+
* Get current USDC liquidity on all bridge networks.
|
|
204
|
+
* Use this before bridging to confirm availability.
|
|
205
|
+
*/
|
|
206
|
+
getBridgeBalances(): Promise<BridgeBalances>;
|
|
207
|
+
/**
|
|
208
|
+
* Bridge USDC from Solana to SKALE Base via x402 payment.
|
|
209
|
+
* This call returns HTTP 402 — pass a createX402Client instance to handle payment automatically.
|
|
210
|
+
*
|
|
211
|
+
* @param amount Amount in USD
|
|
212
|
+
* @param destinationWallet EVM address on SKALE Base
|
|
213
|
+
* @param x402Client A configured createX402Client instance for Solana
|
|
214
|
+
*/
|
|
215
|
+
bridgeSolanaToSkale(amount: number, destinationWallet: string, x402Client: {
|
|
216
|
+
fetch(url: string, init?: RequestInit): Promise<Response>;
|
|
217
|
+
}): Promise<BridgeResult>;
|
|
218
|
+
/**
|
|
219
|
+
* Bridge USDC from SKALE Base to Solana via x402 payment.
|
|
220
|
+
*
|
|
221
|
+
* @param amount Amount in USD
|
|
222
|
+
* @param destinationWallet Solana public key (base58)
|
|
223
|
+
* @param x402Client A configured createX402Client instance for EVM/SKALE Base
|
|
224
|
+
*/
|
|
225
|
+
bridgeSkaleToSolana(amount: number, destinationWallet: string, x402Client: {
|
|
226
|
+
fetch(url: string, init?: RequestInit): Promise<Response>;
|
|
227
|
+
}): Promise<BridgeResult>;
|
|
162
228
|
}
|
|
163
229
|
/**
|
|
164
230
|
* Create a RelAI Management API client.
|
|
@@ -180,4 +246,4 @@ interface RelaiManagementClient {
|
|
|
180
246
|
*/
|
|
181
247
|
declare function createManagementClient(config: ManagementClientConfig): RelaiManagementClient;
|
|
182
248
|
|
|
183
|
-
export { type AgentBootstrapResult, type ApiEndpoint, type ApiEndpointInput, type ApiLogItem, type ApiLogsResult, type ApiPayment, type ApiPaymentsResult, type ApiStats, type CreateApiInput, type ManagementClientConfig, type RelaiApi, type RelaiManagementClient, type UpdateApiInput, bootstrapAgentKeyEvm, bootstrapAgentKeySolana, createManagementClient };
|
|
249
|
+
export { type AgentBootstrapResult, type ApiEndpoint, type ApiEndpointInput, type ApiLogItem, type ApiLogsResult, type ApiPayment, type ApiPaymentsResult, type ApiStats, type BridgeBalances, type BridgeQuoteResult, type BridgeResult, type CreateApiInput, type ManagementClientConfig, type RelaiApi, type RelaiManagementClient, type UpdateApiInput, bootstrapAgentKeyEvm, bootstrapAgentKeySolana, createManagementClient };
|
package/dist/management.d.ts
CHANGED
|
@@ -100,6 +100,40 @@ interface ApiLogsResult {
|
|
|
100
100
|
items: ApiLogItem[];
|
|
101
101
|
nextCursor: string | null;
|
|
102
102
|
}
|
|
103
|
+
interface BridgeQuoteResult {
|
|
104
|
+
inputAmount: number;
|
|
105
|
+
outputAmount: number;
|
|
106
|
+
fee: number;
|
|
107
|
+
feeBps: number;
|
|
108
|
+
inputUsd: number;
|
|
109
|
+
outputUsd: number;
|
|
110
|
+
direction: 'solana-to-skale' | 'skale-to-solana';
|
|
111
|
+
from: string;
|
|
112
|
+
to: string;
|
|
113
|
+
}
|
|
114
|
+
interface BridgeBalances {
|
|
115
|
+
solana: {
|
|
116
|
+
atomic: number;
|
|
117
|
+
usd: number;
|
|
118
|
+
};
|
|
119
|
+
skaleBase: {
|
|
120
|
+
atomic: number;
|
|
121
|
+
usd: number;
|
|
122
|
+
};
|
|
123
|
+
base: {
|
|
124
|
+
atomic: number;
|
|
125
|
+
usd: number;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
interface BridgeResult {
|
|
129
|
+
success: boolean;
|
|
130
|
+
direction: 'solana-to-skale' | 'skale-to-solana';
|
|
131
|
+
destinationWallet: string;
|
|
132
|
+
amountOut: number;
|
|
133
|
+
amountOutUsd: number;
|
|
134
|
+
txHash: string;
|
|
135
|
+
explorerUrl: string;
|
|
136
|
+
}
|
|
103
137
|
interface AgentBootstrapResult {
|
|
104
138
|
key: string;
|
|
105
139
|
label: string;
|
|
@@ -159,6 +193,38 @@ interface RelaiManagementClient {
|
|
|
159
193
|
from?: string;
|
|
160
194
|
cursor?: string;
|
|
161
195
|
}): Promise<ApiLogsResult>;
|
|
196
|
+
/**
|
|
197
|
+
* Get a bridge quote — fee and net output for a given USD amount.
|
|
198
|
+
* @param amount Amount in USD (e.g. 10.0)
|
|
199
|
+
* @param from Source network: 'solana' | 'skale-base' (default: 'solana')
|
|
200
|
+
*/
|
|
201
|
+
getBridgeQuote(amount: number, from?: 'solana' | 'skale-base'): Promise<BridgeQuoteResult>;
|
|
202
|
+
/**
|
|
203
|
+
* Get current USDC liquidity on all bridge networks.
|
|
204
|
+
* Use this before bridging to confirm availability.
|
|
205
|
+
*/
|
|
206
|
+
getBridgeBalances(): Promise<BridgeBalances>;
|
|
207
|
+
/**
|
|
208
|
+
* Bridge USDC from Solana to SKALE Base via x402 payment.
|
|
209
|
+
* This call returns HTTP 402 — pass a createX402Client instance to handle payment automatically.
|
|
210
|
+
*
|
|
211
|
+
* @param amount Amount in USD
|
|
212
|
+
* @param destinationWallet EVM address on SKALE Base
|
|
213
|
+
* @param x402Client A configured createX402Client instance for Solana
|
|
214
|
+
*/
|
|
215
|
+
bridgeSolanaToSkale(amount: number, destinationWallet: string, x402Client: {
|
|
216
|
+
fetch(url: string, init?: RequestInit): Promise<Response>;
|
|
217
|
+
}): Promise<BridgeResult>;
|
|
218
|
+
/**
|
|
219
|
+
* Bridge USDC from SKALE Base to Solana via x402 payment.
|
|
220
|
+
*
|
|
221
|
+
* @param amount Amount in USD
|
|
222
|
+
* @param destinationWallet Solana public key (base58)
|
|
223
|
+
* @param x402Client A configured createX402Client instance for EVM/SKALE Base
|
|
224
|
+
*/
|
|
225
|
+
bridgeSkaleToSolana(amount: number, destinationWallet: string, x402Client: {
|
|
226
|
+
fetch(url: string, init?: RequestInit): Promise<Response>;
|
|
227
|
+
}): Promise<BridgeResult>;
|
|
162
228
|
}
|
|
163
229
|
/**
|
|
164
230
|
* Create a RelAI Management API client.
|
|
@@ -180,4 +246,4 @@ interface RelaiManagementClient {
|
|
|
180
246
|
*/
|
|
181
247
|
declare function createManagementClient(config: ManagementClientConfig): RelaiManagementClient;
|
|
182
248
|
|
|
183
|
-
export { type AgentBootstrapResult, type ApiEndpoint, type ApiEndpointInput, type ApiLogItem, type ApiLogsResult, type ApiPayment, type ApiPaymentsResult, type ApiStats, type CreateApiInput, type ManagementClientConfig, type RelaiApi, type RelaiManagementClient, type UpdateApiInput, bootstrapAgentKeyEvm, bootstrapAgentKeySolana, createManagementClient };
|
|
249
|
+
export { type AgentBootstrapResult, type ApiEndpoint, type ApiEndpointInput, type ApiLogItem, type ApiLogsResult, type ApiPayment, type ApiPaymentsResult, type ApiStats, type BridgeBalances, type BridgeQuoteResult, type BridgeResult, type CreateApiInput, type ManagementClientConfig, type RelaiApi, type RelaiManagementClient, type UpdateApiInput, bootstrapAgentKeyEvm, bootstrapAgentKeySolana, createManagementClient };
|
package/dist/management.js
CHANGED
|
@@ -58,6 +58,29 @@ function createManagementClient(config) {
|
|
|
58
58
|
}
|
|
59
59
|
return res.json();
|
|
60
60
|
}
|
|
61
|
+
async function bridgeReq(method, path, x402Client, body) {
|
|
62
|
+
const res = await x402Client.fetch(`${base}${path}`, {
|
|
63
|
+
method,
|
|
64
|
+
headers: { ...headers, "Content-Type": "application/json" },
|
|
65
|
+
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
66
|
+
});
|
|
67
|
+
if (!res.ok) {
|
|
68
|
+
const text = await res.text().catch(() => "");
|
|
69
|
+
let parsed = {};
|
|
70
|
+
try {
|
|
71
|
+
parsed = JSON.parse(text);
|
|
72
|
+
} catch {
|
|
73
|
+
}
|
|
74
|
+
if (res.status === 503 && parsed["reason"] === "insufficient_liquidity") {
|
|
75
|
+
const avail = parsed["available"];
|
|
76
|
+
throw new Error(
|
|
77
|
+
`Bridge temporarily unavailable \u2014 insufficient liquidity` + (avail != null ? ` (available: $${Number(avail).toFixed(2)} USDC)` : "")
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
throw new Error(`[relai-bridge] ${method} ${path} \u2192 ${res.status}: ${text}`);
|
|
81
|
+
}
|
|
82
|
+
return res.json();
|
|
83
|
+
}
|
|
61
84
|
return {
|
|
62
85
|
// ── APIs ──────────────────────────────────────────────────────────────
|
|
63
86
|
createApi(input) {
|
|
@@ -102,6 +125,30 @@ function createManagementClient(config) {
|
|
|
102
125
|
if (options.cursor) params.set("cursor", options.cursor);
|
|
103
126
|
const qs = params.toString() ? `?${params}` : "";
|
|
104
127
|
return req("GET", `/v1/apis/${apiId}/logs${qs}`);
|
|
128
|
+
},
|
|
129
|
+
// ── Bridge ──────────────────────────────────────────────────
|
|
130
|
+
getBridgeQuote(amount, from = "solana") {
|
|
131
|
+
const params = new URLSearchParams({ amount: String(amount), from });
|
|
132
|
+
return req("GET", `/v1/bridge/quote?${params}`);
|
|
133
|
+
},
|
|
134
|
+
getBridgeBalances() {
|
|
135
|
+
return req("GET", "/v1/bridge/balances");
|
|
136
|
+
},
|
|
137
|
+
async bridgeSolanaToSkale(amount, destinationWallet, x402Client) {
|
|
138
|
+
return bridgeReq(
|
|
139
|
+
"POST",
|
|
140
|
+
"/v1/bridge/solana-to-skale",
|
|
141
|
+
x402Client,
|
|
142
|
+
{ amount, destinationWallet }
|
|
143
|
+
);
|
|
144
|
+
},
|
|
145
|
+
async bridgeSkaleToSolana(amount, destinationWallet, x402Client) {
|
|
146
|
+
return bridgeReq(
|
|
147
|
+
"POST",
|
|
148
|
+
"/v1/bridge/skale-to-solana",
|
|
149
|
+
x402Client,
|
|
150
|
+
{ amount, destinationWallet }
|
|
151
|
+
);
|
|
105
152
|
}
|
|
106
153
|
};
|
|
107
154
|
}
|
package/dist/management.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/management.ts"],"sourcesContent":["// src/management.ts\n// RelAI Management API client — create and manage monetised APIs programmatically.\n// Docs: https://relai.fi/documentation/management-api\n\nconst RELAI_API_BASE = 'https://api.relai.fi';\nconst BOOTSTRAP_URL = `${RELAI_API_BASE}/mcp/management/bootstrap/agent`;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ManagementClientConfig {\n /** Service key (sk_live_...) for authenticating management API calls */\n serviceKey: string;\n /** Override base URL (default: https://api.relai.fi) */\n baseUrl?: string;\n}\n\nexport interface RelaiApi {\n apiId: string;\n name: string;\n description?: string;\n baseUrl: string;\n subdomain?: string | null;\n network: string;\n facilitator: string;\n x402Version: number;\n status: string;\n merchantWallet: string;\n solanaWallet?: string | null;\n /** EVM wallet for cross-chain payments. Only relevant when network is Solana. */\n evmCrossChainWallet?: string | null;\n websiteUrl?: string;\n logoUrl?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ApiEndpointInput {\n path: string;\n method: string;\n usdPrice: number;\n enabled?: boolean;\n}\n\nexport interface ApiEndpoint extends ApiEndpointInput {\n network: string;\n enabled: boolean;\n}\n\nexport interface CreateApiInput {\n name: string;\n baseUrl: string;\n merchantWallet: string;\n /** Solana wallet for cross-chain payments. Only relevant when network is EVM. */\n solanaWallet?: string;\n /** EVM wallet for cross-chain payments. Only relevant when network is Solana. */\n evmCrossChainWallet?: string;\n network: string;\n description?: string;\n websiteUrl?: string;\n logoUrl?: string;\n endpoints?: ApiEndpointInput[];\n}\n\nexport interface UpdateApiInput {\n name?: string;\n description?: string;\n baseUrl?: string;\n merchantWallet?: string;\n /** Solana wallet for cross-chain payments. Set to null to remove. */\n solanaWallet?: string | null;\n /** EVM wallet for cross-chain payments. Set to null to remove. */\n evmCrossChainWallet?: string | null;\n websiteUrl?: string;\n logoUrl?: string;\n}\n\nexport interface ApiStats {\n apiId: string;\n totalRequests: number;\n totalRevenue: number;\n currency: string;\n}\n\nexport interface ApiPayment {\n transaction: string;\n path: string;\n method: string;\n amount: number;\n currency: string;\n network: string;\n status: string;\n success: boolean;\n payer: string;\n createdAt: string;\n}\n\nexport interface ApiPaymentsResult {\n apiId: string;\n payments: ApiPayment[];\n nextCursor: string | null;\n}\n\nexport interface ApiLogItem {\n id: string;\n timestamp: string;\n method: string;\n path: string;\n status: string;\n cost: number;\n currency: string;\n duration: number;\n transaction: string;\n network: string;\n success: boolean;\n payer: string;\n}\n\nexport interface ApiLogsResult {\n items: ApiLogItem[];\n nextCursor: string | null;\n}\n\nexport interface AgentBootstrapResult {\n key: string;\n label: string;\n active: boolean;\n createdAt: string;\n}\n\n// ============================================================================\n// Agent bootstrap (autonomous key provisioning)\n// ============================================================================\n\n/**\n * Bootstrap a service key for a Solana agent.\n * Run once — store the returned key securely.\n *\n * @param keypair A Solana Keypair (from @solana/web3.js)\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeySolana(\n keypair: { publicKey: { toBase58(): string }; secretKey: Uint8Array },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const { sign } = await import('tweetnacl');\n\n const publicKey = keypair.publicKey.toBase58();\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2 — sign\n const msgBytes = new TextEncoder().encode(message);\n const sigBytes = sign.detached(msgBytes, keypair.secretKey);\n const signature = Buffer.from(sigBytes).toString('base64');\n\n // Step 3 — get service key\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n/**\n * Bootstrap a service key for an EVM agent.\n * Run once — store the returned key securely.\n *\n * @param wallet An ethers.js Wallet or Signer with address + signMessage\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeyEvm(\n wallet: { address: string; signMessage(message: string): Promise<string> },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const publicKey = wallet.address;\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2+3 — sign and get key\n const signature = await wallet.signMessage(message);\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n// ============================================================================\n// Management client\n// ============================================================================\n\nexport interface RelaiManagementClient {\n // APIs\n createApi(input: CreateApiInput): Promise<RelaiApi>;\n listApis(): Promise<RelaiApi[]>;\n getApi(apiId: string): Promise<RelaiApi>;\n updateApi(apiId: string, input: UpdateApiInput): Promise<RelaiApi>;\n deleteApi(apiId: string): Promise<{ success: boolean; apiId: string }>;\n\n // Pricing\n getPricing(apiId: string): Promise<{ apiId: string; endpoints: ApiEndpoint[] }>;\n setPricing(apiId: string, endpoints: ApiEndpointInput[]): Promise<{ success: boolean; apiId: string; updated: number }>;\n\n // Analytics\n getStats(apiId: string): Promise<ApiStats>;\n getPayments(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiPaymentsResult>;\n getLogs(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiLogsResult>;\n}\n\n/**\n * Create a RelAI Management API client.\n *\n * @example\n * ```typescript\n * import { createManagementClient } from '@relai-fi/x402/management';\n *\n * const mgmt = createManagementClient({ serviceKey: process.env.RELAI_SERVICE_KEY! });\n *\n * const api = await mgmt.createApi({\n * name: 'My ML API',\n * baseUrl: 'https://inference.example.com',\n * merchantWallet: '0xYourWallet',\n * network: 'base',\n * endpoints: [{ path: '/v1/predict', method: 'post', usdPrice: 0.05 }],\n * });\n * ```\n */\nexport function createManagementClient(config: ManagementClientConfig): RelaiManagementClient {\n const base = (config.baseUrl ?? RELAI_API_BASE).replace(/\\/$/, '');\n const headers = {\n 'X-Service-Key': config.serviceKey,\n 'Content-Type': 'application/json',\n };\n\n async function req<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${base}${path}`, {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`[relai-mgmt] ${method} ${path} → ${res.status}: ${text}`);\n }\n return res.json() as Promise<T>;\n }\n\n return {\n // ── APIs ──────────────────────────────────────────────────────────────\n\n createApi(input) {\n return req<RelaiApi>('POST', '/v1/apis', input);\n },\n\n async listApis() {\n const data = await req<{ apis: RelaiApi[] }>('GET', '/v1/apis');\n return data.apis;\n },\n\n getApi(apiId) {\n return req<RelaiApi>('GET', `/v1/apis/${apiId}`);\n },\n\n updateApi(apiId, input) {\n return req<RelaiApi>('PATCH', `/v1/apis/${apiId}`, input);\n },\n\n deleteApi(apiId) {\n return req<{ success: boolean; apiId: string }>('DELETE', `/v1/apis/${apiId}`);\n },\n\n // ── Pricing ──────────────────────────────────────────────────────────\n\n getPricing(apiId) {\n return req<{ apiId: string; endpoints: ApiEndpoint[] }>('GET', `/v1/apis/${apiId}/pricing`);\n },\n\n setPricing(apiId, endpoints) {\n return req<{ success: boolean; apiId: string; updated: number }>('PUT', `/v1/apis/${apiId}/pricing`, { endpoints });\n },\n\n // ── Analytics ────────────────────────────────────────────────────────\n\n getStats(apiId) {\n return req<ApiStats>('GET', `/v1/apis/${apiId}/stats`);\n },\n\n getPayments(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiPaymentsResult>('GET', `/v1/apis/${apiId}/payments${qs}`);\n },\n\n getLogs(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiLogsResult>('GET', `/v1/apis/${apiId}/logs${qs}`);\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/management.ts"],"sourcesContent":["// src/management.ts\n// RelAI Management API client — create and manage monetised APIs programmatically.\n// Docs: https://relai.fi/documentation/management-api\n\nconst RELAI_API_BASE = 'https://api.relai.fi';\nconst BOOTSTRAP_URL = `${RELAI_API_BASE}/mcp/management/bootstrap/agent`;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ManagementClientConfig {\n /** Service key (sk_live_...) for authenticating management API calls */\n serviceKey: string;\n /** Override base URL (default: https://api.relai.fi) */\n baseUrl?: string;\n}\n\nexport interface RelaiApi {\n apiId: string;\n name: string;\n description?: string;\n baseUrl: string;\n subdomain?: string | null;\n network: string;\n facilitator: string;\n x402Version: number;\n status: string;\n merchantWallet: string;\n solanaWallet?: string | null;\n /** EVM wallet for cross-chain payments. Only relevant when network is Solana. */\n evmCrossChainWallet?: string | null;\n websiteUrl?: string;\n logoUrl?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ApiEndpointInput {\n path: string;\n method: string;\n usdPrice: number;\n enabled?: boolean;\n}\n\nexport interface ApiEndpoint extends ApiEndpointInput {\n network: string;\n enabled: boolean;\n}\n\nexport interface CreateApiInput {\n name: string;\n baseUrl: string;\n merchantWallet: string;\n /** Solana wallet for cross-chain payments. Only relevant when network is EVM. */\n solanaWallet?: string;\n /** EVM wallet for cross-chain payments. Only relevant when network is Solana. */\n evmCrossChainWallet?: string;\n network: string;\n description?: string;\n websiteUrl?: string;\n logoUrl?: string;\n endpoints?: ApiEndpointInput[];\n}\n\nexport interface UpdateApiInput {\n name?: string;\n description?: string;\n baseUrl?: string;\n merchantWallet?: string;\n /** Solana wallet for cross-chain payments. Set to null to remove. */\n solanaWallet?: string | null;\n /** EVM wallet for cross-chain payments. Set to null to remove. */\n evmCrossChainWallet?: string | null;\n websiteUrl?: string;\n logoUrl?: string;\n}\n\nexport interface ApiStats {\n apiId: string;\n totalRequests: number;\n totalRevenue: number;\n currency: string;\n}\n\nexport interface ApiPayment {\n transaction: string;\n path: string;\n method: string;\n amount: number;\n currency: string;\n network: string;\n status: string;\n success: boolean;\n payer: string;\n createdAt: string;\n}\n\nexport interface ApiPaymentsResult {\n apiId: string;\n payments: ApiPayment[];\n nextCursor: string | null;\n}\n\nexport interface ApiLogItem {\n id: string;\n timestamp: string;\n method: string;\n path: string;\n status: string;\n cost: number;\n currency: string;\n duration: number;\n transaction: string;\n network: string;\n success: boolean;\n payer: string;\n}\n\nexport interface ApiLogsResult {\n items: ApiLogItem[];\n nextCursor: string | null;\n}\n\n// ── Bridge types ─────────────────────────────────────────────────────────────\n\nexport interface BridgeQuoteResult {\n inputAmount: number;\n outputAmount: number;\n fee: number;\n feeBps: number;\n inputUsd: number;\n outputUsd: number;\n direction: 'solana-to-skale' | 'skale-to-solana';\n from: string;\n to: string;\n}\n\nexport interface BridgeBalances {\n solana: { atomic: number; usd: number };\n skaleBase: { atomic: number; usd: number };\n base: { atomic: number; usd: number };\n}\n\nexport interface BridgeResult {\n success: boolean;\n direction: 'solana-to-skale' | 'skale-to-solana';\n destinationWallet: string;\n amountOut: number;\n amountOutUsd: number;\n txHash: string;\n explorerUrl: string;\n}\n\nexport interface AgentBootstrapResult {\n key: string;\n label: string;\n active: boolean;\n createdAt: string;\n}\n\n// ============================================================================\n// Agent bootstrap (autonomous key provisioning)\n// ============================================================================\n\n/**\n * Bootstrap a service key for a Solana agent.\n * Run once — store the returned key securely.\n *\n * @param keypair A Solana Keypair (from @solana/web3.js)\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeySolana(\n keypair: { publicKey: { toBase58(): string }; secretKey: Uint8Array },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const { sign } = await import('tweetnacl');\n\n const publicKey = keypair.publicKey.toBase58();\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2 — sign\n const msgBytes = new TextEncoder().encode(message);\n const sigBytes = sign.detached(msgBytes, keypair.secretKey);\n const signature = Buffer.from(sigBytes).toString('base64');\n\n // Step 3 — get service key\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n/**\n * Bootstrap a service key for an EVM agent.\n * Run once — store the returned key securely.\n *\n * @param wallet An ethers.js Wallet or Signer with address + signMessage\n * @param label Human-readable label for the key\n */\nexport async function bootstrapAgentKeyEvm(\n wallet: { address: string; signMessage(message: string): Promise<string> },\n label = 'agent',\n): Promise<AgentBootstrapResult> {\n const publicKey = wallet.address;\n\n // Step 1 — request challenge\n const challengeRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey }),\n });\n if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n const { message } = await challengeRes.json() as { message: string };\n\n // Step 2+3 — sign and get key\n const signature = await wallet.signMessage(message);\n const keyRes = await fetch(BOOTSTRAP_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publicKey, signature, message, label }),\n });\n if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n// ============================================================================\n// Management client\n// ============================================================================\n\nexport interface RelaiManagementClient {\n // APIs\n createApi(input: CreateApiInput): Promise<RelaiApi>;\n listApis(): Promise<RelaiApi[]>;\n getApi(apiId: string): Promise<RelaiApi>;\n updateApi(apiId: string, input: UpdateApiInput): Promise<RelaiApi>;\n deleteApi(apiId: string): Promise<{ success: boolean; apiId: string }>;\n\n // Pricing\n getPricing(apiId: string): Promise<{ apiId: string; endpoints: ApiEndpoint[] }>;\n setPricing(apiId: string, endpoints: ApiEndpointInput[]): Promise<{ success: boolean; apiId: string; updated: number }>;\n\n // Analytics\n getStats(apiId: string): Promise<ApiStats>;\n getPayments(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiPaymentsResult>;\n getLogs(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiLogsResult>;\n\n // Bridge\n /**\n * Get a bridge quote — fee and net output for a given USD amount.\n * @param amount Amount in USD (e.g. 10.0)\n * @param from Source network: 'solana' | 'skale-base' (default: 'solana')\n */\n getBridgeQuote(amount: number, from?: 'solana' | 'skale-base'): Promise<BridgeQuoteResult>;\n\n /**\n * Get current USDC liquidity on all bridge networks.\n * Use this before bridging to confirm availability.\n */\n getBridgeBalances(): Promise<BridgeBalances>;\n\n /**\n * Bridge USDC from Solana to SKALE Base via x402 payment.\n * This call returns HTTP 402 — pass a createX402Client instance to handle payment automatically.\n *\n * @param amount Amount in USD\n * @param destinationWallet EVM address on SKALE Base\n * @param x402Client A configured createX402Client instance for Solana\n */\n bridgeSolanaToSkale(\n amount: number,\n destinationWallet: string,\n x402Client: { fetch(url: string, init?: RequestInit): Promise<Response> },\n ): Promise<BridgeResult>;\n\n /**\n * Bridge USDC from SKALE Base to Solana via x402 payment.\n *\n * @param amount Amount in USD\n * @param destinationWallet Solana public key (base58)\n * @param x402Client A configured createX402Client instance for EVM/SKALE Base\n */\n bridgeSkaleToSolana(\n amount: number,\n destinationWallet: string,\n x402Client: { fetch(url: string, init?: RequestInit): Promise<Response> },\n ): Promise<BridgeResult>;\n}\n\n/**\n * Create a RelAI Management API client.\n *\n * @example\n * ```typescript\n * import { createManagementClient } from '@relai-fi/x402/management';\n *\n * const mgmt = createManagementClient({ serviceKey: process.env.RELAI_SERVICE_KEY! });\n *\n * const api = await mgmt.createApi({\n * name: 'My ML API',\n * baseUrl: 'https://inference.example.com',\n * merchantWallet: '0xYourWallet',\n * network: 'base',\n * endpoints: [{ path: '/v1/predict', method: 'post', usdPrice: 0.05 }],\n * });\n * ```\n */\nexport function createManagementClient(config: ManagementClientConfig): RelaiManagementClient {\n const base = (config.baseUrl ?? RELAI_API_BASE).replace(/\\/$/, '');\n const headers = {\n 'X-Service-Key': config.serviceKey,\n 'Content-Type': 'application/json',\n };\n\n async function req<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${base}${path}`, {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`[relai-mgmt] ${method} ${path} → ${res.status}: ${text}`);\n }\n return res.json() as Promise<T>;\n }\n\n async function bridgeReq<T>(\n method: string,\n path: string,\n x402Client: { fetch(url: string, init?: RequestInit): Promise<Response> },\n body?: unknown,\n ): Promise<T> {\n const res = await x402Client.fetch(`${base}${path}`, {\n method,\n headers: { ...headers, 'Content-Type': 'application/json' },\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n let parsed: Record<string, unknown> = {};\n try { parsed = JSON.parse(text); } catch { /* ignore */ }\n if (res.status === 503 && parsed['reason'] === 'insufficient_liquidity') {\n const avail = parsed['available'] as number | undefined;\n throw new Error(\n `Bridge temporarily unavailable — insufficient liquidity` +\n (avail != null ? ` (available: $${Number(avail).toFixed(2)} USDC)` : ''),\n );\n }\n throw new Error(`[relai-bridge] ${method} ${path} → ${res.status}: ${text}`);\n }\n return res.json() as Promise<T>;\n }\n\n return {\n // ── APIs ──────────────────────────────────────────────────────────────\n\n createApi(input) {\n return req<RelaiApi>('POST', '/v1/apis', input);\n },\n\n async listApis() {\n const data = await req<{ apis: RelaiApi[] }>('GET', '/v1/apis');\n return data.apis;\n },\n\n getApi(apiId) {\n return req<RelaiApi>('GET', `/v1/apis/${apiId}`);\n },\n\n updateApi(apiId, input) {\n return req<RelaiApi>('PATCH', `/v1/apis/${apiId}`, input);\n },\n\n deleteApi(apiId) {\n return req<{ success: boolean; apiId: string }>('DELETE', `/v1/apis/${apiId}`);\n },\n\n // ── Pricing ──────────────────────────────────────────────────────────\n\n getPricing(apiId) {\n return req<{ apiId: string; endpoints: ApiEndpoint[] }>('GET', `/v1/apis/${apiId}/pricing`);\n },\n\n setPricing(apiId, endpoints) {\n return req<{ success: boolean; apiId: string; updated: number }>('PUT', `/v1/apis/${apiId}/pricing`, { endpoints });\n },\n\n // ── Analytics ────────────────────────────────────────────────────────\n\n getStats(apiId) {\n return req<ApiStats>('GET', `/v1/apis/${apiId}/stats`);\n },\n\n getPayments(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiPaymentsResult>('GET', `/v1/apis/${apiId}/payments${qs}`);\n },\n\n getLogs(apiId, options = {}) {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', String(options.limit));\n if (options.from) params.set('from', options.from);\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString() ? `?${params}` : '';\n return req<ApiLogsResult>('GET', `/v1/apis/${apiId}/logs${qs}`);\n },\n\n // ── Bridge ──────────────────────────────────────────────────\n\n getBridgeQuote(amount, from = 'solana') {\n const params = new URLSearchParams({ amount: String(amount), from });\n return req<BridgeQuoteResult>('GET', `/v1/bridge/quote?${params}`);\n },\n\n getBridgeBalances() {\n return req<BridgeBalances>('GET', '/v1/bridge/balances');\n },\n\n async bridgeSolanaToSkale(amount, destinationWallet, x402Client) {\n return bridgeReq<BridgeResult>(\n 'POST',\n '/v1/bridge/solana-to-skale',\n x402Client,\n { amount, destinationWallet },\n );\n },\n\n async bridgeSkaleToSolana(amount, destinationWallet, x402Client) {\n return bridgeReq<BridgeResult>(\n 'POST',\n '/v1/bridge/skale-to-solana',\n x402Client,\n { amount, destinationWallet },\n );\n },\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/react/index.cjs
CHANGED
|
@@ -35,6 +35,7 @@ var import_spl_token = require("@solana/spl-token");
|
|
|
35
35
|
var RELAI_FACILITATOR_URL = "https://facilitator.x402.fi";
|
|
36
36
|
var NETWORK_CAIP2 = {
|
|
37
37
|
"solana": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
|
|
38
|
+
"solana-devnet": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
|
|
38
39
|
"base": "eip155:8453",
|
|
39
40
|
"avalanche": "eip155:43114",
|
|
40
41
|
"skale-base": "eip155:1187947933",
|
|
@@ -66,6 +67,14 @@ var NETWORK_TOKENS = {
|
|
|
66
67
|
decimals: 6
|
|
67
68
|
}
|
|
68
69
|
],
|
|
70
|
+
"solana-devnet": [
|
|
71
|
+
{
|
|
72
|
+
address: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
|
|
73
|
+
symbol: "USDC",
|
|
74
|
+
name: "USD Coin (Devnet)",
|
|
75
|
+
decimals: 6
|
|
76
|
+
}
|
|
77
|
+
],
|
|
69
78
|
"base": [
|
|
70
79
|
{ address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", symbol: "USDC", name: "USD Coin", decimals: 6, domainVersion: "2", isStableUsd: true }
|
|
71
80
|
],
|
|
@@ -190,6 +199,7 @@ var NETWORK_TOKENS = {
|
|
|
190
199
|
};
|
|
191
200
|
var USDC_ADDRESSES = {
|
|
192
201
|
"solana": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
202
|
+
"solana-devnet": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
|
|
193
203
|
"base": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
194
204
|
"avalanche": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
|
|
195
205
|
"skale-base": "0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",
|
|
@@ -201,6 +211,7 @@ var USDC_ADDRESSES = {
|
|
|
201
211
|
};
|
|
202
212
|
var EXPLORER_TX_URL = {
|
|
203
213
|
"solana": (tx) => `https://solscan.io/tx/${tx}`,
|
|
214
|
+
"solana-devnet": (tx) => `https://solscan.io/tx/${tx}?cluster=devnet`,
|
|
204
215
|
"base": (tx) => `https://basescan.org/tx/${tx}`,
|
|
205
216
|
"avalanche": (tx) => `https://snowtrace.io/tx/${tx}`,
|
|
206
217
|
"skale-base": (tx) => `https://skale-base-explorer.skalenodes.com/tx/${tx}`,
|
|
@@ -212,6 +223,7 @@ var EXPLORER_TX_URL = {
|
|
|
212
223
|
};
|
|
213
224
|
var NETWORK_LABELS = {
|
|
214
225
|
"solana": "Solana",
|
|
226
|
+
"solana-devnet": "Solana Devnet",
|
|
215
227
|
"base": "Base",
|
|
216
228
|
"avalanche": "Avalanche",
|
|
217
229
|
"skale-base": "SKALE Base",
|
|
@@ -227,6 +239,7 @@ var USDC_SOLANA = USDC_ADDRESSES["solana"];
|
|
|
227
239
|
var USDC_BASE = USDC_ADDRESSES["base"];
|
|
228
240
|
var RELAI_NETWORKS = [
|
|
229
241
|
"solana",
|
|
242
|
+
"solana-devnet",
|
|
230
243
|
"base",
|
|
231
244
|
"avalanche",
|
|
232
245
|
"skale-base",
|
|
@@ -237,7 +250,7 @@ var RELAI_NETWORKS = [
|
|
|
237
250
|
"telos"
|
|
238
251
|
];
|
|
239
252
|
function isSolana(network) {
|
|
240
|
-
return network === "solana" || network.startsWith("solana:");
|
|
253
|
+
return network === "solana" || network === "solana-devnet" || network.startsWith("solana:");
|
|
241
254
|
}
|
|
242
255
|
function isEvm(network) {
|
|
243
256
|
return ["base", "avalanche", "skale-base", "skale-base-sepolia", "skale-bite", "polygon", "ethereum", "telos"].includes(network) || network.startsWith("eip155:");
|