
wallet_did = """
type EventKind = variant {
  CyclesSent: record {
    to: principal;
    amount: nat64;
    refund: nat64;
  };
  CyclesReceived: record {
    from: principal;
    amount: nat64;
    memo: opt text;
  };
  AddressAdded: record {
    id: principal;
    name: opt text;
    role: Role;
  };
  AddressRemoved: record {
    id: principal;
  };
  CanisterCreated: record {
    canister: principal;
    cycles: nat64;
  };
  CanisterCalled: record {
    canister: principal;
    method_name: text;
    cycles: nat64;
  };
  WalletDeployed: record {
    canister: principal;
  }
};

type EventKind128 = variant {
  CyclesSent: record {
    to: principal;
    amount: nat;
    refund: nat;
  };
  CyclesReceived: record {
    from: principal;
    amount: nat;
    memo: opt text;
  };
    AddressAdded: record {
    id: principal;
    name: opt text;
    role: Role;
  };
  AddressRemoved: record {
    id: principal;
  };
  CanisterCreated: record {
    canister: principal;
    cycles: nat;
  };
  CanisterCalled: record {
    canister: principal;
    method_name: text;
    cycles: nat;
  };
  WalletDeployed: record {
    canister: principal;
  };
};

type Event = record {
  id: nat32;
  timestamp: nat64;
  kind: EventKind;
};

type Event128 = record {
  id: nat32;
  timestamp: nat64;
  kind: EventKind128;
};

type Role = variant {
  Contact;
  Custodian;
  Controller;
};

type Kind = variant {
  Unknown;
  User;
  Canister;
};

// An entry in the address book. It must have an ID and a role.
type AddressEntry = record {
  id: principal;
  name: opt text;
  kind: Kind;
  role: Role;
};

type ManagedCanisterInfo = record {
  id: principal;
  name: opt text;
  created_at: nat64;
};

type ManagedCanisterEventKind = variant {
  CyclesSent: record {
    amount: nat64;
    refund: nat64;
  };
  Called: record {
    method_name: text;
    cycles: nat64;
  };
  Created: record {
    cycles: nat64;
  };
};

type ManagedCanisterEventKind128 = variant {
  CyclesSent: record {
    amount: nat;
    refund: nat;
  };
  Called: record {
    method_name: text;
    cycles: nat;
  };
  Created: record {
    cycles: nat;
  };
};

type ManagedCanisterEvent = record {
  id: nat32;
  timestamp: nat64;
  kind: ManagedCanisterEventKind;
};

type ManagedCanisterEvent128 = record {
  id: nat32;
  timestamp: nat64;
  kind: ManagedCanisterEventKind128;
};

type ReceiveOptions = record {
  memo: opt text;
};

type WalletResultCreate = variant {
  Ok : record { canister_id: principal };
  Err: text;
};

type WalletResult = variant {
  Ok : null;
  Err : text;
};

type WalletResultCall = variant {
  Ok : record { return: blob };
  Err : text;
};

type CanisterSettings = record {
  controller: opt principal;
  controllers: opt vec principal;
  compute_allocation: opt nat;
  memory_allocation: opt nat;
  freezing_threshold: opt nat;
};

type CreateCanisterArgs = record {
  cycles: nat64;
  settings: CanisterSettings;
};

type CreateCanisterArgs128 = record {
  cycles: nat;
  settings: CanisterSettings;
};

// Assets
type HeaderField = record { text; text; };

type HttpRequest = record {
  method: text;
  url: text;
  headers: vec HeaderField;
  body: blob;
};

type HttpResponse = record {
  status_code: nat16;
  headers: vec HeaderField;
  body: blob;
  streaming_strategy: opt StreamingStrategy;
};

type StreamingCallbackHttpResponse = record {
  body: blob;
  token: opt Token;
};

type Token = record {};

type StreamingStrategy = variant {
  Callback: record {
    callback: func (Token) -> (StreamingCallbackHttpResponse) query;
    token: Token;
  };
};

service : {
  wallet_api_version: () -> (text) query;

  // Wallet Name
  name: () -> (opt text) query;
  set_name: (text) -> ();

  // Controller Management
  get_controllers: () -> (vec principal) query;
  add_controller: (principal) -> ();
  remove_controller: (principal) -> (WalletResult);

  // Custodian Management
  get_custodians: () -> (vec principal) query;
  authorize: (principal) -> ();
  deauthorize: (principal) -> (WalletResult);

  // Cycle Management
  wallet_balance: () -> (record { amount: nat64 }) query;
  wallet_balance128: () -> (record { amount: nat }) query;
  wallet_send: (record { canister: principal; amount: nat64 }) -> (WalletResult);
  wallet_send128: (record { canister: principal; amount: nat }) -> (WalletResult);
  wallet_receive: (opt ReceiveOptions) -> ();  // Endpoint for receiving cycles.

  // Managing canister
  wallet_create_canister: (CreateCanisterArgs) -> (WalletResultCreate);
  wallet_create_canister128: (CreateCanisterArgs128) -> (WalletResultCreate);

  wallet_create_wallet: (CreateCanisterArgs) -> (WalletResultCreate);
  wallet_create_wallet128: (CreateCanisterArgs128) -> (WalletResultCreate);

  wallet_store_wallet_wasm: (record {
    wasm_module: blob;
  }) -> ();

  // Call Forwarding
  wallet_call: (record {
    canister: principal;
    method_name: text;
    args: blob;
    cycles: nat64;
  }) -> (WalletResultCall);
  wallet_call128: (record {
    canister: principal;
    method_name: text;
    args: blob;
    cycles: nat;
  }) -> (WalletResultCall);

  // Address book
  add_address: (address: AddressEntry) -> ();
  list_addresses: () -> (vec AddressEntry) query;
  remove_address: (address: principal) -> (WalletResult);

  // Events
  // If `from` is not specified, it will start 20 from the end; if `to` is not specified, it will stop at the end
  get_events: (opt record { from: opt nat32; to: opt nat32; }) -> (vec Event) query;
  get_events128: (opt record { from: opt nat32; to: opt nat32; }) -> (vec Event128) query;
  get_chart: (opt record { count: opt nat32; precision: opt nat64; } ) -> (vec record { nat64; nat64; }) query;

  // Managed canisters
  list_managed_canisters: (record { from: opt nat32; to: opt nat32; }) -> (vec ManagedCanisterInfo, nat32) query;
  // If `from` is not specified, it will start 20 from the end; if `to` is not specified, it will stop at the end
  get_managed_canister_events: (record { canister: principal; from: opt nat32; to: opt nat32; }) -> (opt vec ManagedCanisterEvent) query;
  get_managed_canister_events128: (record { canister: principal; from: opt nat32; to: opt nat32; }) -> (opt vec ManagedCanisterEvent128) query;
  set_short_name: (principal, opt text) -> (opt ManagedCanisterInfo);

  // Assets
  http_request: (request: HttpRequest) -> (HttpResponse) query;
}
"""

from .canister import Canister

class CyclesWallet(Canister):
    def __init__(self, agent, wallet_id):
        super().__init__(agent, wallet_id, wallet_did)