// myAccountCredit provides functions to manage a user's credit account // An account exists inside of the account credit servers // It is used to fund messages, mate/host identities, profiles, and reports on the network. // Users interface with their accounts using their account private keys. package myAccountCredit //TODO: Complete this package // It must function similarly to a cryptocurrency wallet // Each key corresponds to an identifier or a cryptocurrency address // We keep track of the balance of each account // We add the balance of all accounts to get the total balance // We must be able to send to other accounts via their identifier. // -We may have to merge all credit to a single account, unless we implement the ability to spend from multiple in the same transaction // We must show a fresh receiving address every time the user wants to add credit or share their identifier // -A fresh address is one that has never received credit // We do this because address/identifier reuse is bad for privacy. // For example, if a user shared their identifier to receive funds, they should be able to // share a different, fresh identifier in the future to add more funds import "seekia/internal/convertCurrencies" import "seekia/internal/helpers" import "seekia/internal/mySeedPhrases" import "seekia/internal/network/accountKeys" import "errors" //Outputs: // -bool: Parameters exist // -float64: Specified currency balance // -error func GetMyCreditAccountBalanceInAnyCurrency(myIdentityType string, networkType byte, currencyCode string)(bool, float64, error){ isValid := helpers.VerifyNetworkType(networkType) if (isValid == false){ networkTypeString := helpers.ConvertByteToString(networkType) return false, 0, errors.New("GetMyCreditAccountBalanceInAnyCurrency called with invalid networkType: " + networkTypeString) } //TODO totalAppCurrencyBalance := float64(0) cryptocurrencyNamesList := []string{"Ethereum", "Cardano"} for _, cryptocurrencyName := range cryptocurrencyNamesList{ currentCryptoUnitsBalance := int64(100) parametersExist, accountCreditAppCurrencyBalance, err := convertCurrencies.ConvertCryptoAtomicUnitsToAnyCurrency(networkType, cryptocurrencyName, currentCryptoUnitsBalance, currencyCode) if (err != nil){ return false, 0, err } if (parametersExist == false){ return false, 0, nil } totalAppCurrencyBalance += accountCreditAppCurrencyBalance } return true, totalAppCurrencyBalance, nil } //Outputs: // -bool: Identity exists // -string: Unused account identifier // -error func GetAnUnusedCreditAccountIdentifier(myIdentityType string, networkType byte)(bool, string, error){ if (myIdentityType != "Mate" && myIdentityType != "Host" && myIdentityType != "Moderator"){ return false, "", errors.New("GetAnUnusedCreditAccountIdentifier called with invalid identityType: " + myIdentityType) } isValid := helpers.VerifyNetworkType(networkType) if (isValid == false){ networkTypeString := helpers.ConvertByteToString(networkType) return false, "", errors.New("GetAnUnusedCreditAccountIdentifier called with invalid networkType: " + networkTypeString) } identityFound, mySeedPhraseHash, err := mySeedPhrases.GetMySeedPhraseHash(myIdentityType) if (err != nil) { return false, "", err } if (identityFound == false){ return false, "", nil } //TODO: Get unused keys index // We must keep track of which identifiers are used, and skip those indexes. keysIndex := 1 accountPublicKey, _, err := accountKeys.GetCreditAccountPublicPrivateKeys(mySeedPhraseHash, networkType, "Identifier", keysIndex) if (err != nil) { return false, "", err } accountIdentifier, err := accountKeys.GetAccountIdentifierFromAccountPublicKey(accountPublicKey) if (err != nil) { return false, "", err } return true, accountIdentifier, nil } // This will return a fresh account credit crypto address // We must avoid address reuse //Outputs: // -bool: Identity exists // -string: Credit account crypto receiving address // -error func GetAnUnusedCreditAccountCryptoAddress(myIdentityType string, networkType byte, cryptocurrencyName string)(bool, string, error){ if (myIdentityType != "Mate" && myIdentityType != "Host" && myIdentityType != "Moderator"){ return false, "", errors.New("GetAnUnusedCreditAccountCryptoAddress called with invalid identityType: " + myIdentityType) } isValid := helpers.VerifyNetworkType(networkType) if (isValid == false){ networkTypeString := helpers.ConvertByteToString(networkType) return false, "", errors.New("GetAnUnusedCreditAccountCryptoAddress called with invalid networkType: " + networkTypeString) } if (cryptocurrencyName != "Ethereum" && cryptocurrencyName != "Cardano"){ return false, "", errors.New("GetAnUnusedCreditAccountCryptoAddress called with invalid cryptocurrencyName: " + cryptocurrencyName) } identityFound, mySeedPhraseHash, err := mySeedPhrases.GetMySeedPhraseHash(myIdentityType) if (err != nil) { return false, "", err } if (identityFound == false){ return false, "", nil } //TODO: Get unused keys index keysIndex := 1 accountPublicKey, _, err := accountKeys.GetCreditAccountPublicPrivateKeys(mySeedPhraseHash, networkType, cryptocurrencyName, keysIndex) if (err != nil) { return false, "", err } _, err = accountKeys.GetCryptocurrencyAddressFromAccountPublicKey(cryptocurrencyName, accountPublicKey) if (err != nil) { return false, "", err } //TODO: Return address once Seekia is complete return true, "SeekiaIsNotCompleteYet", nil } //Outputs: // -bool: Parameters exist // -bool: Sufficient credit exist // -error func FreezeCreditForMessage(messageIdentifier [20]byte, messageNetworkType byte, messageDuration int, messageSize int)(bool, bool, error){ //TODO // Adjust amount of funds frozen as the cost of messages changes? return true, true, nil } //Outputs: // -bool: Frozen credit found // -error func ReleaseFrozenCreditForMessage(messageIdentifier [20]byte)(bool, error){ //TODO return true, nil }