agent-operator 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 (46) hide show
  1. package/README.md +171 -0
  2. package/dist/cli/add-wallet.d.ts +1 -0
  3. package/dist/cli/add-wallet.js +15 -0
  4. package/dist/cli/index.d.ts +2 -0
  5. package/dist/cli/index.js +34 -0
  6. package/dist/cli/init.d.ts +1 -0
  7. package/dist/cli/init.js +200 -0
  8. package/dist/cli/status.d.ts +1 -0
  9. package/dist/cli/status.js +25 -0
  10. package/dist/config.d.ts +18 -0
  11. package/dist/config.js +57 -0
  12. package/dist/connectors/base.d.ts +12 -0
  13. package/dist/connectors/base.js +119 -0
  14. package/dist/connectors/solana.d.ts +12 -0
  15. package/dist/connectors/solana.js +91 -0
  16. package/dist/connectors/tempo.d.ts +12 -0
  17. package/dist/connectors/tempo.js +102 -0
  18. package/dist/connectors/types.d.ts +28 -0
  19. package/dist/connectors/types.js +1 -0
  20. package/dist/index.d.ts +15 -0
  21. package/dist/index.js +16 -0
  22. package/dist/notifications/engine.d.ts +11 -0
  23. package/dist/notifications/engine.js +64 -0
  24. package/dist/notifications/telegram.d.ts +21 -0
  25. package/dist/notifications/telegram.js +146 -0
  26. package/dist/notifications/types.d.ts +32 -0
  27. package/dist/notifications/types.js +1 -0
  28. package/dist/operator.d.ts +26 -0
  29. package/dist/operator.js +206 -0
  30. package/dist/policies/daily-limit.d.ts +1 -0
  31. package/dist/policies/daily-limit.js +15 -0
  32. package/dist/policies/engine.d.ts +16 -0
  33. package/dist/policies/engine.js +24 -0
  34. package/dist/policies/high-value-gate.d.ts +2 -0
  35. package/dist/policies/high-value-gate.js +28 -0
  36. package/dist/policies/low-balance.d.ts +3 -0
  37. package/dist/policies/low-balance.js +23 -0
  38. package/dist/policies/new-counterparty.d.ts +2 -0
  39. package/dist/policies/new-counterparty.js +29 -0
  40. package/dist/policies/session-cap.d.ts +1 -0
  41. package/dist/policies/session-cap.js +11 -0
  42. package/dist/policies/types.d.ts +18 -0
  43. package/dist/policies/types.js +20 -0
  44. package/dist/spend/tracker.d.ts +17 -0
  45. package/dist/spend/tracker.js +101 -0
  46. package/package.json +55 -0
@@ -0,0 +1,91 @@
1
+ import { getWallet, signTransaction } from "@open-wallet-standard/core";
2
+ import { solana } from "@solana/mpp/client";
3
+ import { Mppx } from "mppx/client";
4
+ export class SolanaConnector {
5
+ chain = "solana";
6
+ sessions = new Map();
7
+ async openSession(params) {
8
+ const { service, maxBudget, walletId } = params;
9
+ const wallet = getWallet(walletId);
10
+ const solanaAccount = wallet.accounts.find((a) => a.chainId.startsWith("solana"));
11
+ if (!solanaAccount) {
12
+ throw new Error(`Wallet '${walletId}' has no Solana account`);
13
+ }
14
+ // create an OWS-backed TransactionSigner compatible with @solana/kit
15
+ const { address } = await import("@solana/kit");
16
+ const owsSigner = {
17
+ address: address(solanaAccount.address),
18
+ async signTransactions(transactions) {
19
+ return Promise.all(transactions.map(async (tx) => {
20
+ const txBytes = typeof tx.serialize === "function"
21
+ ? tx.serialize()
22
+ : new Uint8Array(tx);
23
+ const txHex = Buffer.from(txBytes).toString("hex");
24
+ const result = signTransaction(walletId, "solana:mainnet-beta", txHex);
25
+ // return the signed transaction bytes
26
+ return Buffer.from(result.signature, "hex");
27
+ }));
28
+ },
29
+ };
30
+ // create @solana/mpp charge method with OWS signer
31
+ const chargeMethod = solana.charge({
32
+ signer: owsSigner,
33
+ });
34
+ const mppxClient = Mppx.create({
35
+ methods: [chargeMethod],
36
+ });
37
+ // initiate payment via the 402 challenge-response flow
38
+ await mppxClient.fetch(service, {
39
+ headers: { "X-Max-Budget": String(maxBudget) },
40
+ });
41
+ const sessionId = crypto.randomUUID();
42
+ this.sessions.set(sessionId, {
43
+ sessionId,
44
+ service,
45
+ maxBudget,
46
+ mppxClient,
47
+ });
48
+ return {
49
+ sessionId,
50
+ chain: this.chain,
51
+ service,
52
+ maxBudget,
53
+ spent: 0,
54
+ status: "active",
55
+ };
56
+ }
57
+ async closeSession(sessionId) {
58
+ const session = this.sessions.get(sessionId);
59
+ if (!session) {
60
+ throw new Error(`Session '${sessionId}' not found`);
61
+ }
62
+ this.sessions.delete(sessionId);
63
+ return {
64
+ sessionId,
65
+ totalSpent: session.maxBudget,
66
+ };
67
+ }
68
+ async getBalance(walletId) {
69
+ const wallet = getWallet(walletId);
70
+ const solanaAccount = wallet.accounts.find((a) => a.chainId.startsWith("solana"));
71
+ if (!solanaAccount) {
72
+ return { chain: this.chain, amount: 0, currency: "USDC" };
73
+ }
74
+ try {
75
+ const { createSolanaRpc } = await import("@solana/kit");
76
+ const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
77
+ // get native SOL balance
78
+ const { value } = await rpc
79
+ .getBalance(solanaAccount.address)
80
+ .send();
81
+ return {
82
+ chain: this.chain,
83
+ amount: Number(value) / 1e9,
84
+ currency: "SOL",
85
+ };
86
+ }
87
+ catch {
88
+ return { chain: this.chain, amount: 0, currency: "SOL" };
89
+ }
90
+ }
91
+ }
@@ -0,0 +1,12 @@
1
+ import type { Connector, Session, SessionResult, Balance } from "./types.js";
2
+ export declare class TempoConnector implements Connector {
3
+ chain: string;
4
+ private sessions;
5
+ openSession(params: {
6
+ service: string;
7
+ maxBudget: number;
8
+ walletId: string;
9
+ }): Promise<Session>;
10
+ closeSession(sessionId: string): Promise<SessionResult>;
11
+ getBalance(walletId: string): Promise<Balance>;
12
+ }
@@ -0,0 +1,102 @@
1
+ import { tempo as tempoClient } from "mppx/client";
2
+ import { signMessage, getWallet } from "@open-wallet-standard/core";
3
+ export class TempoConnector {
4
+ chain = "tempo";
5
+ sessions = new Map();
6
+ async openSession(params) {
7
+ const { service, maxBudget, walletId } = params;
8
+ const wallet = getWallet(walletId);
9
+ const evmAccount = wallet.accounts.find((a) => a.chainId.startsWith("eip155"));
10
+ if (!evmAccount) {
11
+ throw new Error(`Wallet '${walletId}' has no EVM account for Tempo`);
12
+ }
13
+ // create OWS-backed viem custom account for Tempo
14
+ const { toAccount } = await import("viem/accounts");
15
+ const { createPublicClient, http } = await import("viem");
16
+ const { tempo: tempoChain } = await import("viem/chains");
17
+ const owsAccount = toAccount({
18
+ address: evmAccount.address,
19
+ async signMessage({ message }) {
20
+ const msgStr = typeof message === "string"
21
+ ? message
22
+ : Buffer.from(message.raw).toString("hex");
23
+ const result = signMessage(walletId, "eip155:1", msgStr);
24
+ return result.signature;
25
+ },
26
+ async signTransaction(tx) {
27
+ const { signTransaction: owsSignTx } = await import("@open-wallet-standard/core");
28
+ const txHex = typeof tx === "string" ? tx : JSON.stringify(tx);
29
+ const result = owsSignTx(walletId, "eip155:1", txHex);
30
+ return result.signature;
31
+ },
32
+ async signTypedData(typedData) {
33
+ const { signTypedData: owsSignTyped } = await import("@open-wallet-standard/core");
34
+ const result = owsSignTyped(walletId, "eip155:1", JSON.stringify(typedData));
35
+ return result.signature;
36
+ },
37
+ });
38
+ // create the session manager with Tempo's built-in method
39
+ const manager = tempoClient.session({
40
+ account: owsAccount,
41
+ maxDeposit: String(maxBudget),
42
+ });
43
+ // open the session (creates on-chain channel)
44
+ await manager.open({ deposit: BigInt(Math.floor(maxBudget * 1e6)) });
45
+ const sessionId = manager.channelId ?? crypto.randomUUID();
46
+ this.sessions.set(sessionId, {
47
+ sessionId,
48
+ service,
49
+ maxBudget,
50
+ manager,
51
+ });
52
+ return {
53
+ sessionId,
54
+ chain: this.chain,
55
+ service,
56
+ maxBudget,
57
+ spent: 0,
58
+ status: "active",
59
+ };
60
+ }
61
+ async closeSession(sessionId) {
62
+ const session = this.sessions.get(sessionId);
63
+ if (!session) {
64
+ throw new Error(`Session '${sessionId}' not found`);
65
+ }
66
+ const receipt = await session.manager.close();
67
+ this.sessions.delete(sessionId);
68
+ const totalSpent = Number(session.manager.cumulative) / 1e6;
69
+ return {
70
+ sessionId,
71
+ totalSpent,
72
+ refund: session.maxBudget - totalSpent,
73
+ };
74
+ }
75
+ async getBalance(walletId) {
76
+ const wallet = getWallet(walletId);
77
+ const evmAccount = wallet.accounts.find((a) => a.chainId.startsWith("eip155"));
78
+ if (!evmAccount) {
79
+ return { chain: this.chain, amount: 0, currency: "TEMPO" };
80
+ }
81
+ try {
82
+ const { createPublicClient, http, parseAbi } = await import("viem");
83
+ const { tempo: tempoChain } = await import("viem/chains");
84
+ const client = createPublicClient({
85
+ chain: tempoChain,
86
+ transport: http(),
87
+ });
88
+ // query native balance
89
+ const balance = await client.getBalance({
90
+ address: evmAccount.address,
91
+ });
92
+ return {
93
+ chain: this.chain,
94
+ amount: Number(balance) / 1e18,
95
+ currency: "TEMPO",
96
+ };
97
+ }
98
+ catch {
99
+ return { chain: this.chain, amount: 0, currency: "TEMPO" };
100
+ }
101
+ }
102
+ }
@@ -0,0 +1,28 @@
1
+ export interface Connector {
2
+ chain: string;
3
+ openSession(params: {
4
+ service: string;
5
+ maxBudget: number;
6
+ walletId: string;
7
+ }): Promise<Session>;
8
+ closeSession(sessionId: string): Promise<SessionResult>;
9
+ getBalance(walletId: string): Promise<Balance>;
10
+ }
11
+ export interface Session {
12
+ sessionId: string;
13
+ chain: string;
14
+ service: string;
15
+ maxBudget: number;
16
+ spent: number;
17
+ status: "active" | "closed";
18
+ }
19
+ export interface SessionResult {
20
+ sessionId: string;
21
+ totalSpent: number;
22
+ refund?: number;
23
+ }
24
+ export interface Balance {
25
+ chain: string;
26
+ amount: number;
27
+ currency: string;
28
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import { Operator } from "./operator.js";
2
+ export { Operator } from "./operator.js";
3
+ export type { PayParams } from "./operator.js";
4
+ export { loadConfig } from "./config.js";
5
+ export type { OperatorConfig, WalletConfig, NotificationConfig } from "./config.js";
6
+ export type { Connector, Session, SessionResult, Balance } from "./connectors/types.js";
7
+ export { TempoConnector } from "./connectors/tempo.js";
8
+ export { BaseConnector } from "./connectors/base.js";
9
+ export { SolanaConnector } from "./connectors/solana.js";
10
+ export type { NotificationProvider, AgentEvent, ApprovalEvent, ApprovalResult, AlertsConfig, } from "./notifications/types.js";
11
+ export { TelegramProvider } from "./notifications/telegram.js";
12
+ export { NotificationEngine } from "./notifications/engine.js";
13
+ export { PolicyDeniedError, ConnectorError } from "./policies/types.js";
14
+ export type { PoliciesConfig } from "./policies/types.js";
15
+ export declare function createOperator(configPath?: string): Promise<Operator>;
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ import { loadConfig } from "./config.js";
2
+ import { Operator } from "./operator.js";
3
+ export { Operator } from "./operator.js";
4
+ export { loadConfig } from "./config.js";
5
+ export { TempoConnector } from "./connectors/tempo.js";
6
+ export { BaseConnector } from "./connectors/base.js";
7
+ export { SolanaConnector } from "./connectors/solana.js";
8
+ export { TelegramProvider } from "./notifications/telegram.js";
9
+ export { NotificationEngine } from "./notifications/engine.js";
10
+ export { PolicyDeniedError, ConnectorError } from "./policies/types.js";
11
+ export async function createOperator(configPath) {
12
+ const config = loadConfig(configPath);
13
+ const operator = new Operator(config);
14
+ await operator.start();
15
+ return operator;
16
+ }
@@ -0,0 +1,11 @@
1
+ import type { NotificationProvider, AgentEvent, ApprovalEvent, ApprovalResult, AlertsConfig } from "./types.js";
2
+ export declare class NotificationEngine {
3
+ private providers;
4
+ registerProvider(walletName: string, provider: NotificationProvider): void;
5
+ getProvider(walletName: string): NotificationProvider;
6
+ startAll(): Promise<void>;
7
+ stopAll(): Promise<void>;
8
+ notify(walletName: string, event: AgentEvent, alerts: AlertsConfig): Promise<void>;
9
+ requestApproval(walletName: string, event: ApprovalEvent): Promise<ApprovalResult>;
10
+ private shouldSend;
11
+ }
@@ -0,0 +1,64 @@
1
+ export class NotificationEngine {
2
+ providers = new Map();
3
+ registerProvider(walletName, provider) {
4
+ this.providers.set(walletName, provider);
5
+ }
6
+ getProvider(walletName) {
7
+ const provider = this.providers.get(walletName);
8
+ if (!provider) {
9
+ throw new Error(`No notification provider configured for wallet '${walletName}'`);
10
+ }
11
+ return provider;
12
+ }
13
+ async startAll() {
14
+ const started = new Set();
15
+ for (const [, provider] of this.providers) {
16
+ // avoid starting the same provider instance twice
17
+ // (multiple wallets could share a provider)
18
+ if (!started.has(provider.name)) {
19
+ await provider.start();
20
+ started.add(provider.name);
21
+ }
22
+ }
23
+ }
24
+ async stopAll() {
25
+ const stopped = new Set();
26
+ for (const [, provider] of this.providers) {
27
+ if (!stopped.has(provider.name)) {
28
+ await provider.stop();
29
+ stopped.add(provider.name);
30
+ }
31
+ }
32
+ }
33
+ async notify(walletName, event, alerts) {
34
+ if (!this.shouldSend(event.type, alerts))
35
+ return;
36
+ const provider = this.providers.get(walletName);
37
+ if (!provider)
38
+ return;
39
+ try {
40
+ await provider.send(event);
41
+ }
42
+ catch (err) {
43
+ console.error(`[agent-operator] notification failed for '${walletName}':`, err);
44
+ }
45
+ }
46
+ async requestApproval(walletName, event) {
47
+ const provider = this.getProvider(walletName);
48
+ return provider.sendWithApproval(event);
49
+ }
50
+ shouldSend(type, alerts) {
51
+ switch (type) {
52
+ case "low_balance":
53
+ return alerts.lowBalance !== false;
54
+ case "policy_denied":
55
+ return alerts.policyDenied !== false;
56
+ case "daily_summary":
57
+ return alerts.dailySummary !== false;
58
+ case "session_opened":
59
+ return alerts.sessionOpened === true;
60
+ default:
61
+ return true;
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,21 @@
1
+ import type { NotificationProvider, AgentEvent, ApprovalEvent, ApprovalResult } from "./types.js";
2
+ interface TelegramConfig {
3
+ botToken: string;
4
+ chatId: string;
5
+ approvalTimeout?: number;
6
+ }
7
+ export declare class TelegramProvider implements NotificationProvider {
8
+ name: string;
9
+ private bot;
10
+ private pendingApprovals;
11
+ private config;
12
+ private started;
13
+ constructor(config: TelegramConfig);
14
+ start(): Promise<void>;
15
+ stop(): Promise<void>;
16
+ send(event: AgentEvent): Promise<void>;
17
+ sendWithApproval(event: ApprovalEvent): Promise<ApprovalResult>;
18
+ private formatEvent;
19
+ private formatApprovalEvent;
20
+ }
21
+ export {};
@@ -0,0 +1,146 @@
1
+ import { Bot } from "grammy";
2
+ const DEFAULT_APPROVAL_TIMEOUT = 5 * 60 * 1000; // 5 minutes
3
+ export class TelegramProvider {
4
+ name = "telegram";
5
+ bot = null;
6
+ pendingApprovals = new Map();
7
+ config;
8
+ started = false;
9
+ constructor(config) {
10
+ this.config = config;
11
+ }
12
+ async start() {
13
+ if (this.started)
14
+ return;
15
+ try {
16
+ this.bot = new Bot(this.config.botToken);
17
+ this.bot.on("callback_query:data", async (ctx) => {
18
+ const data = ctx.callbackQuery.data;
19
+ const [action, approvalId] = data.split(":");
20
+ const resolve = this.pendingApprovals.get(approvalId);
21
+ if (!resolve) {
22
+ await ctx.answerCallbackQuery({ text: "This approval has expired." });
23
+ return;
24
+ }
25
+ const approved = action === "approve";
26
+ resolve(approved);
27
+ this.pendingApprovals.delete(approvalId);
28
+ await ctx.answerCallbackQuery({
29
+ text: approved ? "Approved" : "Rejected",
30
+ });
31
+ await ctx.editMessageReplyMarkup({ reply_markup: undefined });
32
+ await ctx.api.sendMessage(this.config.chatId, approved ? "✅ Approved" : "❌ Rejected");
33
+ });
34
+ this.bot.start({ drop_pending_updates: true });
35
+ this.started = true;
36
+ }
37
+ catch (err) {
38
+ throw new Error(`Failed to start TelegramProvider. Is 'grammy' installed? ${err}`);
39
+ }
40
+ }
41
+ async stop() {
42
+ if (this.bot && this.started) {
43
+ await this.bot.stop();
44
+ this.started = false;
45
+ }
46
+ for (const [id, resolve] of this.pendingApprovals) {
47
+ resolve(false);
48
+ this.pendingApprovals.delete(id);
49
+ }
50
+ }
51
+ async send(event) {
52
+ const message = this.formatEvent(event);
53
+ await this.bot.api.sendMessage(this.config.chatId, message, {
54
+ parse_mode: "HTML",
55
+ });
56
+ }
57
+ async sendWithApproval(event) {
58
+ const message = this.formatApprovalEvent(event);
59
+ const timeout = this.config.approvalTimeout ?? DEFAULT_APPROVAL_TIMEOUT;
60
+ await this.bot.api.sendMessage(this.config.chatId, message, {
61
+ parse_mode: "HTML",
62
+ reply_markup: {
63
+ inline_keyboard: [
64
+ [
65
+ {
66
+ text: "✅ Approve",
67
+ callback_data: `approve:${event.approvalId}`,
68
+ },
69
+ {
70
+ text: "❌ Reject",
71
+ callback_data: `reject:${event.approvalId}`,
72
+ },
73
+ ],
74
+ ],
75
+ },
76
+ });
77
+ return new Promise((resolve) => {
78
+ const timer = setTimeout(() => {
79
+ this.pendingApprovals.delete(event.approvalId);
80
+ resolve({ approved: false, approvalId: event.approvalId });
81
+ }, timeout);
82
+ this.pendingApprovals.set(event.approvalId, (approved) => {
83
+ clearTimeout(timer);
84
+ resolve({ approved, approvalId: event.approvalId });
85
+ });
86
+ });
87
+ }
88
+ formatEvent(event) {
89
+ const { type, walletName, chain, data } = event;
90
+ switch (type) {
91
+ case "low_balance":
92
+ return [
93
+ `⚠️ <b>Low Balance</b>`,
94
+ `Wallet: ${walletName}${chain ? ` on ${chain}` : ""}`,
95
+ `Balance: $${data.balance}`,
96
+ `Threshold: $${data.threshold}`,
97
+ ].join("\n");
98
+ case "policy_denied":
99
+ return [
100
+ `❌ <b>Policy Denied</b>`,
101
+ `Wallet: ${walletName}`,
102
+ `Reason: ${data.reason}`,
103
+ `Details: ${JSON.stringify(data.details)}`,
104
+ ].join("\n");
105
+ case "daily_summary":
106
+ return [
107
+ `📊 <b>Daily Summary</b>`,
108
+ `Wallet: ${walletName}`,
109
+ `Spent: $${data.spent} / $${data.dailyLimit}`,
110
+ `Sessions: ${data.sessionCount}`,
111
+ `Balance: $${data.balance}`,
112
+ ].join("\n");
113
+ case "session_opened":
114
+ return [
115
+ `🔗 <b>Session Opened</b>`,
116
+ `Wallet: ${walletName}${chain ? ` on ${chain}` : ""}`,
117
+ `Service: ${data.service}`,
118
+ `Budget: $${data.maxBudget}`,
119
+ ].join("\n");
120
+ default:
121
+ return `📢 ${type}: ${JSON.stringify(data)}`;
122
+ }
123
+ }
124
+ formatApprovalEvent(event) {
125
+ const { type, walletName, chain, data } = event;
126
+ switch (type) {
127
+ case "high_value_tx":
128
+ return [
129
+ `🚨 <b>High Value Transaction</b>`,
130
+ `Wallet: ${walletName}${chain ? ` on ${chain}` : ""}`,
131
+ `Service: ${data.service}`,
132
+ `Amount: $${data.amount}`,
133
+ `Threshold: $${data.threshold}`,
134
+ ].join("\n");
135
+ case "new_counterparty":
136
+ return [
137
+ `👀 <b>New Counterparty</b>`,
138
+ `Wallet: ${walletName}${chain ? ` on ${chain}` : ""}`,
139
+ `Service: ${data.service}`,
140
+ `Max Budget: $${data.maxBudget}`,
141
+ ].join("\n");
142
+ default:
143
+ return `❓ Approval needed: ${JSON.stringify(data)}`;
144
+ }
145
+ }
146
+ }
@@ -0,0 +1,32 @@
1
+ export interface NotificationProvider {
2
+ name: string;
3
+ start(): Promise<void>;
4
+ stop(): Promise<void>;
5
+ send(event: AgentEvent): Promise<void>;
6
+ sendWithApproval(event: ApprovalEvent): Promise<ApprovalResult>;
7
+ }
8
+ export type AgentEventType = "low_balance" | "policy_denied" | "daily_summary" | "session_opened";
9
+ export type ApprovalEventType = "high_value_tx" | "new_counterparty";
10
+ export interface AgentEvent {
11
+ type: AgentEventType;
12
+ walletName: string;
13
+ chain?: string;
14
+ data: Record<string, unknown>;
15
+ timestamp: string;
16
+ }
17
+ export interface ApprovalEvent extends Omit<AgentEvent, "type"> {
18
+ type: ApprovalEventType;
19
+ approvalId: string;
20
+ }
21
+ export interface ApprovalResult {
22
+ approved: boolean;
23
+ approvalId: string;
24
+ }
25
+ export interface AlertsConfig {
26
+ lowBalance?: boolean;
27
+ highValueTx?: boolean;
28
+ newCounterparty?: boolean;
29
+ policyDenied?: boolean;
30
+ dailySummary?: boolean;
31
+ sessionOpened?: boolean;
32
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ import type { OperatorConfig } from "./config.js";
2
+ import type { SessionResult, Balance } from "./connectors/types.js";
3
+ export interface PayParams {
4
+ service: string;
5
+ chain: string;
6
+ maxBudget: number;
7
+ }
8
+ export declare class Operator {
9
+ private config;
10
+ private connectors;
11
+ private notifications;
12
+ private dailySummaryInterval;
13
+ constructor(config: OperatorConfig);
14
+ private initConnectors;
15
+ private initNotifications;
16
+ private createProvider;
17
+ start(): Promise<void>;
18
+ shutdown(): Promise<void>;
19
+ pay(walletName: string, params: PayParams): Promise<SessionResult>;
20
+ getBalance(walletName: string, chain: string): Promise<Balance>;
21
+ closeSession(walletName: string, sessionId: string): Promise<SessionResult>;
22
+ getWalletNames(): string[];
23
+ private getWalletConfig;
24
+ private getConnector;
25
+ private startDailySummary;
26
+ }