All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.klaytn.caver.wallet.KeyringContainer Maven / Gradle / Ivy

There is a newer version: 1.12.2-android
Show newest version
/*
 * Copyright 2020 The caver-java Authors
 *
 * Licensed under the Apache License, Version 2.0 (the “License”);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an “AS IS” BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.klaytn.caver.wallet;

import com.klaytn.caver.transaction.AbstractFeeDelegatedTransaction;
import com.klaytn.caver.transaction.AbstractTransaction;
import com.klaytn.caver.transaction.TransactionHasher;
import com.klaytn.caver.utils.Utils;
import com.klaytn.caver.wallet.keyring.AbstractKeyring;
import com.klaytn.caver.wallet.keyring.KeyringFactory;
import com.klaytn.caver.wallet.keyring.wrapper.KeyringFactoryWrapper;
import com.klaytn.caver.wallet.keyring.MessageSigned;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * Represents a Keyring container which manages keyring.

* To access it from Caver instance, it can be accessed through `caver.wallet`. * @see KeyringFactory * @see AbstractKeyring * @see com.klaytn.caver.wallet.keyring.SingleKeyring * @see com.klaytn.caver.wallet.keyring.MultipleKeyring * @see com.klaytn.caver.wallet.keyring.RoleBasedKeyring */ public class KeyringContainer implements IWallet{ /** * The map where address and keyring are mapped */ Map addressKeyringMap = new HashMap<>(); /** * The KeyringFactoryWrapper instance * This is added to improve "SDK User Experience" * which means giving developers similar development experience with caver-js */ public KeyringFactoryWrapper keyring; /** * Creates KeyringContainer instance. */ public KeyringContainer() { keyring = new KeyringFactoryWrapper(); } /** * Creates KeyringContainer instance. * @param keyrings An list of keyring */ public KeyringContainer(List keyrings) { keyring = new KeyringFactoryWrapper(); keyrings.stream().forEach(this::add); } /** * Generates keyrings in the keyring container with randomly generated key pairs.

*

Example :
     * {@code
     * List addressList = caver.wallet.generate(3);
     * }
     * 
* * @param num The number of keyring to create. * @return List of address generated Keyring instances */ @Override public List generate(int num) { return this.generate(num, null); } /** * Generates keyrings in the keyring container with randomly generated key pairs.

*

Example :
     * {@code
     * List addressList = caver.wallet.generate(3, "entropy");
     * }
     * 
* * @param num The number of keyring to create. * @param entropy A random string to increase entropy. * @return List of address generated Keyring instances */ public List generate(int num, String entropy) { List addressList = new ArrayList<>(); for(int i=0; i *
Example :
     * {@code
     * int size = caver.wallet.length();
     * }
     * 
* * @return int */ public int length() { return this.addressKeyringMap.size(); } /** * Creates a single type keyring instance with given parameters and adds it to the keyringContainer.

* KeyringContainer manages Keyring instance using Map {string:Keyring} which has address as key value.

*

Example :
     * {@code
     * String address = "0x{address}";
     * String key = caver.wallet.keyring.generateSingleKey();
     *
     * SingleKeyring keyring = (SingleKeyring)caver.wallet.newKeyring(address, key);
     * }
     * 
* * @param address The address of the keyring * @param key Private key string * @return AbstractKeyring(SingleKeyring) */ public AbstractKeyring newKeyring(String address, String key) { AbstractKeyring keyring = KeyringFactory.createWithSingleKey(address, key); return this.add(keyring); } /** * Creates a multiple type keyring instance with given parameters and add it to the keyringContainer. * KeyringContainer manages Keyring instance using Map {string:Keyring} which has address as key value. *
Example :
     * {@code
     * String address = "0x{address}";
     * String[] keyArray = caver.wallet.keyring.generateMultipleKeys(3);
     * MultipleKeyring keyring = (MultipleKeyring)caver.wallet.newKeyring(address, keyArray);
     * }
     * 
* * @param address The address of the keyring * @param keys An array of private keys * @return AbstractKeyring(MultipleKeyring) */ public AbstractKeyring newKeyring(String address, String[] keys) { AbstractKeyring keyring = KeyringFactory.createWithMultipleKey(address, keys); return this.add(keyring); } /** * Creates a role-basd type keyring instance with given parameters and add it to the keyringContainer.

* KeyringContainer manages Keyring instance using Map {string:Keyring} which has address as key value.

*

Example :
     * {@code
     * String address = caver.wallet.keyring.generate().getAddress();
     * List privateKeys = caver.wallet.keyring.generateRoleBasedKeys(new int[]{3,4,5});
     *
     * RoleBasedKeyring added = (RoleBasedKeyring)caver.wallet.newKeyring(address, privateKeys);
     * }
     * 
* * @param address The address of the keyring * @param keys A List of private key array * @return AbstractKeyring(RoleBasedKeyring) */ public AbstractKeyring newKeyring(String address, List keys) { AbstractKeyring keyring = KeyringFactory.createWithRoleBasedKey(address, keys); return this.add(keyring); } /** * Updates the keyring inside the keyringContainer.

* Query the keyring to be updated from keyringContainer with the keyring's address,

* and an error occurs when the keyring is not found in the keyringContainer.

*

Example :
     * {@code
     * String updatedAddress = "0x{address}";
     * String newPrivateKey = caver.wallet.keyring.generateSingleKey();
     * SingleKeyring newKeyring = (SingleKeyring)caver.wallet.newKeyring(updatedAddress, newPrivateKey);
     *
     * caver.wallet.updateKeyring(newKeyring);
     * }
     * 
* * @param keyring The keyring with new key * @return AbstractKeyring */ public AbstractKeyring updateKeyring(AbstractKeyring keyring) { AbstractKeyring founded = this.getKeyring(keyring.getAddress()); if(founded == null) { throw new IllegalArgumentException("Failed to find keyring to update."); } this.remove(keyring.getAddress()); return this.add(keyring); } /** * Returns the keyring in container corresponding to the address.

*

Example :
     * String address = "0x{address}";
     * AbstractKeyring keyring = caver.wallet.getKeyring(address);
     * 
* * @param address The address of keyring to query * @return AbstractKeyring */ public AbstractKeyring getKeyring(String address) { if(!Utils.isAddress(address)) { throw new IllegalArgumentException("Invalid address. To get keyring from wallet, you need to pass a valid address string as a parameter."); } AbstractKeyring found = this.addressKeyringMap.get(address.toLowerCase()); return found; } /** * Adds a keyring to the keyringContainer.

*

Example :
     * {@code
     * SingleKeyring keyring = caver.wallet.keyring.generate();
     * caver.wallet.add(keyring);
     * }
     * 
* @param keyring Keyring instance to be added. * @return AbstractKeyring */ public AbstractKeyring add(AbstractKeyring keyring) { if (this.getKeyring(keyring.getAddress()) != null) { throw new IllegalArgumentException("Duplicated Account. Please use updateKeyring() instead"); } AbstractKeyring added = keyring.copy(); this.addressKeyringMap.put(keyring.getAddress().toLowerCase(), added); return added; } /** * Deletes the keyring that associates with the given address from keyringContainer.

*

Example :
     * {@code
     * String address = "0x{address}";
     * caver.wallet.remove(address);
     * }
     * 
* * @param address An address of the keyring to be deleted in keyringContainer * @return boolean */ @Override public boolean remove(String address) { if(!Utils.isAddress(address)) { throw new IllegalArgumentException("To remove keyring, the first parameter should be an address string"); } if(!isExisted(address)) { return false; } //deallocate keyring object created for keyringContainer. AbstractKeyring removed = this.addressKeyringMap.remove(address.toLowerCase()); removed = null; return true; } /** * Signs with data and returns MessageSigned instance that includes 'signature', 'message', and 'messageHash'.

* It automatically set both 'roleIndex' and 'keyIndex' to 0.

*

Example :
     * {@code
     * String address = "0x{address in KeyringContainer}";
     * String data = "hello";
     *
     * MessageSigned signed = caver.wallet.signMessage(address, data);
     * }
     * 
* @param address An address of keyring in keyringContainer * @param data The data string to sign * @return MessageSigned */ public MessageSigned signMessage(String address, String data) { return this.signMessage(address, data, 0, 0); } /** * Signs with data and returns MessageSigned instance that includes 'signature', 'message', and 'messageHash'.

*

Example :
     * {@code
     * String address = "0x{address in KeyringContainer}";
     * String data = "hello";
     * int role = RoleGroup.TRANSACTION;
     * int index = 0;
     *
     * MessageSigned signed = caver.wallet.signMessage(address, data, role, index);
     * }
     * 
* @param address An address of keyring in keyringContainer * @param data The data string to sign. * @param role A number indication the role of the key. see {@link com.klaytn.caver.account.AccountKeyRoleBased.RoleGroup}. * @param index An index of key to use for signing. * @return MessageSigned */ public MessageSigned signMessage(String address, String data, int role, int index) { if(!isExisted(address)) { throw new NullPointerException("Failed to find keyring from wallet with address"); } return this.getKeyring(address).signMessage(data, role, index); } /** * Signs the transaction as a sender of the transaction and appends signatures in the transaction instance using all keys in the Keyring instance corresponding to the address.

*

Example :
     * {@code
     * AbstractTransaction signedTx = caver.wallet.sign("0x{address}", transaction);
     * }
     * 
* * @param address An address of keyring in KeyringContainer. * @param transaction An AbstractTransaction instance to sign. * @return AbstractTransaction * @throws IOException */ @Override public AbstractTransaction sign(String address, AbstractTransaction transaction) throws IOException { return sign(address, transaction, TransactionHasher::getHashForSignature); } /** * Signs the transaction as a sender of the transaction and appends signatures in the transaction instance using all keys in the Keyring instance corresponding to the address.

*

Example :
     * {@code
     * AbstractTransaction signedTx = caver.wallet.sign("0x{address}", transaction, TransactionHasher::getHashForSignature);
     * }
     * 
* * @param address An address of keyring in KeyringContainer. * @param transaction An AbstractTransaction instance to sign. * @param hasher A function to return hash of transaction. * @return AbstractTransaction * @throws IOException */ public AbstractTransaction sign(String address, AbstractTransaction transaction, Function hasher) throws IOException{ if(!isExisted(address)) { throw new NullPointerException("Failed to find keyring from wallet with address"); } return transaction.sign(this.getKeyring(address), hasher); } /** * Signs the transaction as a sender of the transaction and appends signatures in the transaction instance using one key in the keyring instance corresponding to the address.

*

Example :
     * {@code
     * AbstractTransaction signedTx = caver.wallet.sign("0x{address}", transaction, 0);
     * }
     * 
* * @param address An address of keyring in KeyringContainer. * @param transaction An AbstractTransaction instance to sign * @param index An index of key to use for signing. * @return AbstractTransaction * @throws IOException */ public AbstractTransaction sign(String address, AbstractTransaction transaction, int index) throws IOException { return sign(address, transaction, index, TransactionHasher::getHashForSignature); } /** * Signs the transaction as a sender of the transaction and appends signatures in the transaction instance using one key in the keyring instance corresponding to the address.

*

Example :
     * {@code
     * AbstractTransaction signedTx = caver.wallet.sign("0x{address}", transaction, 0, TransactionHasher::getHashForSignature);
     * }
     * 
* * @param address An address of keyring in KeyringContainer. * @param transaction An AbstractTransaction instance to sign. * @param index An index of key to use for signing. * @param hasher A function to return hash of transaction. * @return AbstractTransaction * @throws IOException */ public AbstractTransaction sign(String address, AbstractTransaction transaction, int index, Function hasher) throws IOException { if(!isExisted(address)) { throw new NullPointerException("Failed to find keyring from wallet with address"); } return transaction.sign(this.getKeyring(address), index, hasher); } /** * Signs the FeeDelegatedTransaction as a fee payer of the transaction and appends feePayerSignatures in the transaction instance using all keys in the keyring instance corresponding to the address.

*

Example :
     * {@code
     * AbstractFeeDelegatedTransaction signedTx = caver.wallet.signAsFeePayer("0x{address}", transaction);
     * }
     * 
* @param address An address of keyring in KeyringContainer. * @param transaction An AbstractFeeDelegatedTransaction instance to sign. * @return AbstractFeeDelegatedTransaction * @throws IOException */ @Override public AbstractFeeDelegatedTransaction signAsFeePayer(String address, AbstractFeeDelegatedTransaction transaction) throws IOException { return signAsFeePayer(address, transaction, TransactionHasher::getHashForFeePayerSignature); } /** * Signs the FeeDelegatedTransaction as a fee payer of the transaction and appends feePayerSignatures in the transaction instance using all keys in the keyring instance corresponding to the address.

*

Example :
     * {@code
     * AbstractFeeDelegatedTransaction signedTx = caver.wallet.signAsFeePayer("0x{address}", transaction, TransactionHasher::getHashForSignature);
     * }
     * 
* @param address An address of keyring in KeyringContainer. * @param transaction An AbstractFeeDelegatedTransaction instance to sign. * @param hasher A function to return hash of transaction. * @return AbstractFeeDelegatedTransaction * @throws IOException */ public AbstractFeeDelegatedTransaction signAsFeePayer(String address, AbstractFeeDelegatedTransaction transaction, Function hasher) throws IOException { if(!isExisted(address)) { throw new NullPointerException("Failed to find keyring from wallet with address"); } return transaction.signAsFeePayer(this.getKeyring(address), hasher); } /** * Signs the FeeDelegatedTransaction as a fee payer of the transaction and appends feePayerSignatures in the transaction instance using one key in the keyring corresponding to the address.

*

Example :
     * {@code
     * AbstractFeeDelegatedTransaction signedTx = caver.wallet.signAsFeePayer("0x{address}", transaction, 0);
     * }
     * 
* * @param address An address of keyring in KeyringContainer. * @param transaction An AbstractFeeDelegatedTransaction instance to sign. * @param index An index of key to use for signing. * @return AbstractFeeDelegatedTransaction * @throws IOException */ public AbstractFeeDelegatedTransaction signAsFeePayer(String address, AbstractFeeDelegatedTransaction transaction, int index) throws IOException { return signAsFeePayer(address, transaction, index, TransactionHasher::getHashForFeePayerSignature); } /** * Signs the FeeDelegatedTransaction as a fee payer of the transaction and appends feePayerSignatures in the transaction instance using one key in the keyring corresponding to the address.

*

Example :
     * {@code
     * AbstractFeeDelegatedTransaction signedTx = caver.wallet.signAsFeePayer("0x{address}", transaction, 0, TransactionHasher::getHashForSignature);
     * }
     * 
* * @param address An address of keyring in KeyringContainer. * @param transaction An AbstractFeeDelegatedTransaction instance to sign. * @param index An index of key to user for signing * @param hasher A function to return hash of transaction. * @return AbstractFeeDelegatedTransaction * @throws IOException */ public AbstractFeeDelegatedTransaction signAsFeePayer(String address, AbstractFeeDelegatedTransaction transaction, int index, Function hasher) throws IOException { if(!isExisted(address)) { throw new NullPointerException("Failed to find keyring from wallet with address"); } return transaction.signAsFeePayer(this.getKeyring(address), index, hasher); } /** * Returns true if there is a keyring matching the given address in the wallet.

*

Exampe :
     * {@code
     * boolean isExist = caver.wallet.isExisted("0x{address}");
     * }
     * 
* @param address An address to find keyring in wallet. * @return boolean */ @Override public boolean isExisted(String address) { return this.getKeyring(address) != null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy