# frozen_string_literal: true module CardanoWallet # Init API for Shelley module Shelley def self.new(opt) Init.new opt end ## # Base class for Shelley API class Init < Base # Call API for Wallets # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Wallets def wallets Wallets.new @opt end # API for Addresses # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Addresses def addresses Addresses.new @opt end # API for CoinSelections # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Coin-Selections def coin_selections CoinSelections.new @opt end # API for Transactions # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Transactions def transactions Transactions.new @opt end # API for StakePools # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Stake-Pools def stake_pools StakePools.new @opt end # API for Migrations # @see https://input-output-hk.github.io/cardano-wallet/api/#tag/Migrations def migrations Migrations.new @opt end # API for Keys # @see https://input-output-hk.github.io/cardano-wallet/api/#tag/Keys def keys Keys.new @opt end # API for Assets # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Assets def assets Assets.new @opt end end ## # Base class for Shelley Assets API class Assets < Base # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/mintBurnAssets def mint(wid, mint_burn, pass, metadata = nil, ttl = nil) payload = { mint_burn: mint_burn, passphrase: pass } payload[:metadata] = metadata if metadata payload[:time_to_live] = { quantity: ttl, unit: 'second' } if ttl self.class.post("/wallets/#{wid}/assets", body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) end # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/listAssets # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/getAsset # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/getAssetDefault def get(wid, policy_id = nil, asset_name = nil) ep = "/wallets/#{wid}/assets" ep += "/#{policy_id}" if policy_id ep += "/#{asset_name}" if asset_name self.class.get(ep) end end ## # Base class for Shelley Keys API class Keys < Base # @see https://input-output-hk.github.io/cardano-wallet/api/#operation/signMetadata def sign_metadata(wid, role, index, pass, metadata) payload = { passphrase: pass } payload[:metadata] = metadata if metadata self.class.post("/wallets/#{wid}/signatures/#{role}/#{index}", body: payload.to_json, headers: { 'Content-Type' => 'application/json', 'Accept' => 'application/octet-stream' }) end # @see https://input-output-hk.github.io/cardano-wallet/api/#operation/getWalletKey def get_public_key(wid, role, index, query = {}) query_formatted = query.empty? ? '' : Utils.to_query(query) self.class.get("/wallets/#{wid}/keys/#{role}/#{index}#{query_formatted}") end # @see https://input-output-hk.github.io/cardano-wallet/api/#operation/postAccountKey def create_acc_public_key(wid, index, payload) # payload = { passphrase: pass, format: format, purpose: purpose } Utils.verify_param_is_hash!(payload) self.class.post("/wallets/#{wid}/keys/#{index}", body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) end # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/getAccountKey def get_acc_public_key(wid, query = {}) query_formatted = query.empty? ? '' : Utils.to_query(query) self.class.get("/wallets/#{wid}/keys#{query_formatted}") end end # API for Wallets # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Wallets class Wallets < Base # List all wallets # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/listWallets def list self.class.get('/wallets') end # Get wallet details # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/getWallet def get(wid) self.class.get("/wallets/#{wid}") end # Create a wallet based on the params. # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postWallet # # @example Create wallet from mnemonic sentence # create({name: "Wallet from mnemonic_sentence", # passphrase: "Secure Passphrase", # mnemonic_sentence: %w[story egg fun ... ], # }) # @example Create wallet from pub key # create({name: "Wallet from pub key", # account_public_key: "b47546e...", # address_pool_gap: 20, # }) def create(params) Utils.verify_param_is_hash!(params) self.class.post('/wallets', body: params.to_json, headers: { 'Content-Type' => 'application/json' }) end # Delete wallet # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/deleteWallet def delete(wid) self.class.delete("/wallets/#{wid}") end # Update wallet's metadata # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/putWallet # # @example # update_metadata(wid, {name: "New wallet name"}) def update_metadata(wid, params) Utils.verify_param_is_hash!(params) self.class.put("/wallets/#{wid}", body: params.to_json, headers: { 'Content-Type' => 'application/json' }) end # See wallet's utxo distribution # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/getUTxOsStatistics def utxo(wid) self.class.get("/wallets/#{wid}/statistics/utxos") end # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/getWalletUtxoSnapshot def utxo_snapshot(wid) self.class.get("/wallets/#{wid}/utxo") end # Update wallet's passphrase # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/putWalletPassphrase # # @example # update_passphrase(wid, {old_passphrase: "Secure Passphrase", new_passphrase: "Securer Passphrase"}) def update_passphrase(wid, params) Utils.verify_param_is_hash!(params) self.class.put("/wallets/#{wid}/passphrase", body: params.to_json, headers: { 'Content-Type' => 'application/json' }) end end # API for Addresses # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Addresses class Addresses < Base # List addresses # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/listAddresses # # @example # list(wid, {state: "used"}) def list(wid, query = {}) query_formatted = query.empty? ? '' : Utils.to_query(query) self.class.get("/wallets/#{wid}/addresses#{query_formatted}") end end # API for CoinSelections # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Coin-Selections class CoinSelections < Base # Show random coin selection for particular payment # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/selectCoins # # @example # random(wid, [{addr1: 1000000}, {addr2: 1000000}]) # random(wid, [{ "address": "addr1..", # "amount": { "quantity": 42000000, "unit": "lovelace" }, # "assets": [{"policy_id": "pid", "asset_name": "name", "quantity": 0 } ] } ]) def random(wid, payments, withdrawal = nil, metadata = nil) Utils.verify_param_is_array!(payments) payments_formatted = if payments.any? { |p| p.key?(:address) || p.key?('address') } payments else Utils.format_payments(payments) end payload = { payments: payments_formatted } payload[:withdrawal] = withdrawal if withdrawal payload[:metadata] = metadata if metadata self.class.post("/wallets/#{wid}/coin-selections/random", body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) end # Coin selection -> Delegation action # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/selectCoins # # @example # random(wid, {action: "join", pool: "poolid"}) # random(wid, {action: "quit"}) def random_deleg(wid, deleg_action) Utils.verify_param_is_hash!(deleg_action) self.class.post("/wallets/#{wid}/coin-selections/random", body: { delegation_action: deleg_action }.to_json, headers: { 'Content-Type' => 'application/json' }) end end # API for Transactions # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Transactions class Transactions < Base # Balance transaction # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/balanceTransaction # @param wid [String] source wallet id # @param payload [Hash] payload object def balance(wid, payload) self.class.post("/wallets/#{wid}/transactions-balance", body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) end # Decode transaction # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/decodeTransaction # @param wid [String] source wallet id # @param transaction [String] CBOR base64|base16 encoded transaction def decode(wid, transaction) payload = {} payload[:transaction] = transaction self.class.post("/wallets/#{wid}/transactions-decode", body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) end # Construct transaction # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/constructTransaction # @param wid [String] source wallet id # @param payments [Array of Hashes] full payments payload with assets # @param withdrawal [String or Array] 'self' or mnemonic sentence # @param metadata [Hash] special metadata JSON subset format (cf: https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postTransaction) # @param mint [Array of Hashes] mint object # @param delegations [Array of Hashes] delegations object # @param validity_interval [Hash] validity_interval object def construct(wid, payments = nil, withdrawal = nil, metadata = nil, delegations = nil, mint = nil, validity_interval = nil) payload = {} payload[:payments] = payments if payments payload[:withdrawal] = withdrawal if withdrawal payload[:metadata] = metadata if metadata payload[:mint] = mint if mint payload[:delegations] = delegations if delegations payload[:validity_interval] = validity_interval if validity_interval self.class.post("/wallets/#{wid}/transactions-construct", body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) end # Sign transaction # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/signTransaction # @param wid [String] source wallet id # @param passphrase [String] wallet's passphrase # @param passphrase [String] CBOR transaction data def sign(wid, passphrase, transaction) payload = { 'passphrase' => passphrase, 'transaction' => transaction } self.class.post("/wallets/#{wid}/transactions-sign", body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) end # Get tx by id # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/getTransaction def get(wid, tx_id) self.class.get("/wallets/#{wid}/transactions/#{tx_id}") end # List all wallet's transactions # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/listTransactions # # @example # list(wid, {start: "2012-09-25T10:15:00Z", order: "descending"}) def list(wid, query = {}) query_formatted = query.empty? ? '' : Utils.to_query(query) self.class.get("/wallets/#{wid}/transactions#{query_formatted}") end # Create a transaction from the wallet # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postTransaction # @param wid [String] source wallet id # @param passphrase [String] source wallet's passphrase # @param payments [Array of Hashes] address / amount list or full payments payload with assets # @param withdrawal [String or Array] 'self' or mnemonic sentence # @param metadata [Hash] special metadata JSON subset format (cf: https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postTransaction) # @param ttl [Int] transaction's time-to-live in seconds # # @example # create(wid, passphrase, [{addr1: 1000000}, {addr2: 1000000}], 'self', {"1": "abc"}, ttl = 10) # create(wid, passphrase, [{ "address": "addr1..", # "amount": { "quantity": 42000000, "unit": "lovelace" }, # "assets": [{"policy_id": "pid", "asset_name": "name", "quantity": 0 } ] } ], # 'self', {"1": "abc"}, ttl = 10) def create(wid, passphrase, payments, withdrawal = nil, metadata = nil, ttl = nil) Utils.verify_param_is_array!(payments) payments_formatted = if payments.any? { |p| p.key?(:address) || p.key?('address') } payments else Utils.format_payments(payments) end payload = { payments: payments_formatted, passphrase: passphrase } payload[:withdrawal] = withdrawal if withdrawal payload[:metadata] = metadata if metadata payload[:time_to_live] = { quantity: ttl, unit: 'second' } if ttl self.class.post("/wallets/#{wid}/transactions", body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) end # Estimate fees for transaction # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postTransactionFee # # @example # payment_fees(wid, [{addr1: 1000000}, {addr2: 1000000}], {"1": "abc"}, ttl = 10) # payment_fees(wid, [{ "address": "addr1..", # "amount": { "quantity": 42000000, "unit": "lovelace" }, # "assets": [{"policy_id": "pid", "asset_name": "name", "quantity": 0 } ] } ], # {"1": "abc"}, ttl = 10) def payment_fees(wid, payments, withdrawal = nil, metadata = nil, ttl = nil) Utils.verify_param_is_array!(payments) payments_formatted = if payments.any? { |p| p.key?(:address) || p.key?('address') } payments else Utils.format_payments(payments) end payload = { payments: payments_formatted } payload[:withdrawal] = withdrawal if withdrawal payload[:metadata] = metadata if metadata payload[:time_to_live] = { quantity: ttl, unit: 'second' } if ttl self.class.post("/wallets/#{wid}/payment-fees", body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) end # Forget a transaction # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/deleteTransaction def forget(wid, txid) self.class.delete("/wallets/#{wid}/transactions/#{txid}") end end # API for StakePools # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Stake-Pools class StakePools < Base # Stake pools maintenance actions # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postMaintenanceAction # # @example # maintenance_action({ "maintenance_action": "gc_stake_pools" }) def trigger_maintenance_actions(action = {}) Utils.verify_param_is_hash!(action) self.class.post('/stake-pools/maintenance-actions', body: action.to_json, headers: { 'Content-Type' => 'application/json' }) end # Metdata GC Status # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/getMaintenanceActions def view_maintenance_actions self.class.get('/stake-pools/maintenance-actions') end # List all stake pools # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/listStakePools def list(stake = {}) query = stake.empty? ? '' : Utils.to_query(stake) self.class.get("/stake-pools#{query}") end # List all stake keys # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/listStakeKeys def list_stake_keys(wid) self.class.get("/wallets/#{wid}/stake-keys") end # Join stake pool # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/joinStakePool def join(sp_id, wid, passphrase) self.class.put("/stake-pools/#{sp_id}/wallets/#{wid}", body: { passphrase: passphrase }.to_json, headers: { 'Content-Type' => 'application/json' }) end # Quit stape pool # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/quitStakePool def quit(wid, passphrase) self.class.delete("#{@api}/stake-pools/*/wallets/#{wid}", body: { passphrase: passphrase }.to_json, headers: { 'Content-Type' => 'application/json' }) end # Estimate delegation fees # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/getDelegationFee def delegation_fees(wid) self.class.get("/wallets/#{wid}/delegation-fees") end end # Shelley migrations # @see https://input-output-hk.github.io/cardano-wallet/api/#tag/Migrations class Migrations < Base # Get migration plan # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/createShelleyWalletMigrationPlan def plan(wid, addresses) self.class.post("/wallets/#{wid}/migrations/plan", body: { addresses: addresses }.to_json, headers: { 'Content-Type' => 'application/json' }) end # Migrate all funds from Shelley wallet. # @see https://input-output-hk.github.io/cardano-wallet/api/#operation/migrateShelleyWallet # @param wid [String] wallet id # @param passphrase [String] wallet's passphrase # @param [Array] array of addresses def migrate(wid, passphrase, addresses) self.class.post("/wallets/#{wid}/migrations", body: { addresses: addresses, passphrase: passphrase }.to_json, headers: { 'Content-Type' => 'application/json' }) end end end end