I BUILT AN NFT GAME IN 12 HOURS (Part 5) Error: invalid address

Hi Iโ€™m getting the following error when adding the following lines to main.js. Please let help.

   let array = await contract.methods.getAllTokensForUser(ethereum.selecedAddress).call({from: ethereum.selecedAddress});
   console.log(array);
Uncaught (in promise) Error: invalid address (argument="address", value=undefined, code=INVALID_ARGUMENT, version=address/5.5.0) (argument="user", value=undefined, code=INVALID_ARGUMENT, version=abi/5.0.7)
    at e.value (index.ts:225:28)
    at e.value (index.ts:237:20)
    at e.value (index.ts:241:21)
    at r.value (abstract-coder.ts:68:16)
    at r.value (address.ts:18:18)
    at array.ts:71:19
    at Array.forEach (<anonymous>)
    at y (array.ts:54:12)
    at r.value (tuple.ts:23:16)
    at e.value (abi-coder.ts:106:15)

Here is my amin.js:

/** Connect to Moralis server */

const serverUrl = "xxxxxxx";

const appId = "xxxxxxxxx";

const CONTRACT_ADDRESS = "xxxxxxxx";

Moralis.start({serverUrl, appId});

async function init() {

    try {

        let user = Moralis.User.current();

        if (! user) {

            $("#login_button").click(async () => {

                user = await Moralis.authenticate();

            })

        }

        renderGame();

    } catch (error) {

        console.log(error);

    }

}

async function renderGame() {

    $("#login_button").hide();

    // Get and render propertize from Smart contract

    let petId = 0;

    let abi = await getAbi();

    const web3 = await Moralis.enableWeb3();

    let contract = new web3.eth.Contract(abi, CONTRACT_ADDRESS);

    //console.log(contract);

   let array = await contract.methods.getAllTokensForUser(ethereum.selecedAddress).call({from: ethereum.selecedAddress});

   console.log(array);

    let data = await contract.methods.getTokenDetails(petId).call({from: ethereum.selecedAddress});

    console.log(data);

    renderPet(0,data);

    $("#game").show();

}

function renderPet(id, data){

    $("#pet_id").html(id);

    $("#pet_damage").html(data.damage);

    $("#pet_magic").html(data.magic);

    $("#pet_endurance").html(data.endurance);

    $("#feed_button").attr("data-pet-id", id);  

    let deathTime = new Date( (parseInt(data.lastMeal) + parseInt(data.endurance)) * 1000);

    let now = new Date();

    if (now > deathTime) {

        deathTime = "<b>DEAD</d>"

    }

    $("#pet_starvation_time").html(deathTime);

}

function getAbi() {

    return new Promise((res) => {

        $.getJSON("Token.json", ((json) => {

            res(json.abi);

        }))

    })

}

async function feed(petId){

    let abi = await getAbi();

   

    const web3 = await Moralis.enableWeb3();

    let contract = new web3.eth.Contract(abi, CONTRACT_ADDRESS);

    contract.methods.feed(petId).send({from: ethereum.selectedAddress}).on("receipt", ( () => {

        console.log("done");

        renderGame();

    }))

}

$("#feed_button").click( () => {

    let petId = $("#feed_button").attr("data-pet-id");

    feed(petId);

})

init();

Token.sol

pragma solidity 0.8.11;

import "../node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol";

import "../node_modules/@openzeppelin/contracts/access/Ownable.sol";

contract Token is ERC721, Ownable {

    struct Pet {

        uint8 damage;

        uint8 magic;

        uint256 lastMeal;

        uint256 endurance; //24 hours without food will die

    }

    mapping(uint256 => Pet) private _tokenDetails;

    uint256 nextId = 0;

    constructor(string memory name, string memory symbol)

        ERC721(name, symbol)

    {}

    function getTokenDetails(uint256 tokenId) public view returns (Pet memory) {

        return _tokenDetails[tokenId];

    }

    function mint(

        uint8 damage,

        uint8 magic,

        uint256 endurance

    ) public onlyOwner {

        _tokenDetails[nextId] = Pet(damage, magic, block.timestamp, endurance);

        _safeMint(msg.sender, nextId);

        nextId++;

    }

    function feed(uint256 tokenId) public {

        Pet storage pet = _tokenDetails[tokenId];

        require(pet.lastMeal + pet.endurance > block.timestamp);

        pet.lastMeal = block.timestamp;

    }

    function getAllTokensForUser(address user)

        public

        view

        returns (uint256[] memory)

    {

        uint256 tokenCount = balanceOf(user);

        if (tokenCount == 0) {

            return new uint256[](0);

        } else {

            uint256[] memory result = new uint256[](tokenCount); //uint256?

            uint256 totalPets = nextId;

            uint256 resultIndex = 0;

            uint256 i;

            for (i = 0; i < totalPets; i++) {

                if (ownerOf(i) == user) {

                    result[resultIndex] = i;

                    resultIndex++;

                }

            }

            return result;

        }

    }

    function _beforeTokenTransfer(

        address from,

        address to,

        uint256 tokenId

    ) internal override {

        Pet storage pet = _tokenDetails[tokenId];

        require(pet.lastMeal + pet.endurance > block.timestamp);

    }

}

What line gives that error?

Thanks for your quick reply. The following lines.

  let array = await contract.methods.getAllTokensForUser(ethereum.selecedAddress).call({from: ethereum.selecedAddress});
   console.log(array);

It may also matter what version of Moralis sdk you use. Maybe that address parameter is not defined and that is why it may not work.

In that case what sould I do? If I use the latest SDK, I have to convert the codes to Ether.js and I donโ€™t know how to do it. Can you please send some guidance where I can get resource to do that? or anyway to get the source code of the tutorial made in ether.js?

You can use Moralis sdk version 0.0184 that is latest version with web3 used by default

Yes. I used that version. Here is the code in index.html

<!DOCTYPE html>
<html>
  <head>
    <title>NFT Game</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/web3.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/moralis.js"></script>


    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

    <link rel="stylesheet" href="./style.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  </head>
 
  <body>
   
    <div class="container">
 
      <button id="login_button">Moralis Metamask Login</button>
 
      <div id="game">
        <div class="row">
          <div class="col-md-8">
            
          </div>
 
          <div class="col-md-4 card">
            <img class="card-img-top" src="pet.png" id="pet_image">

            <div class="card-body">
              <div> Id: <span id="pet_id"></span></div>
              <div> Damage: <span id="pet_damage"></span></div>
              <div> Magic: <span id="pet_magic"></span></div>
              <div> Endurance: <span id="pet_endurance"></span></div>
              <div> Time to Starvation: <span id="pet_starvation_time"></span></div>
              <button id="feed_button" class="btn btn-primary btn-block"> Feed</button>      
          </div>
            
          </div>

        </div>
      </div>
 
    </div>
 
 
 
    <script type="text/javascript" src="./main.js"></script>
  </body>
</html>

Ok, now you need to the the address somehow to give it as parameter

Hi, Iโ€™m a good coder. Can please tell, how can I do it?

I have ran
console.log(user);

on the init function. It does not have anything related to ethereum.selecedAddress

Here is the log

ParseUser {id: 'i51HMYUjwBcYQ5igAbyhXUL4', _localId: undefined, _objCount: 0, className: '_User'}
className: "_User"
id: "i51HMYUjwBcYQ5igAbyhXUL4"
_localId: undefined
_objCount: 0
attributes: Object
createdAt: Sat Feb 12 2022 22:05:45 GMT+0600 (Bangladesh Standard Time)
updatedAt: Sat Feb 12 2022 22:06:24 GMT+0600 (Bangladesh Standard Time)
[[Prototype]]: ParseObject
authenticated: ฦ’ ()
constructor: ฦ’ ParseUser(attributes /*: ?AttributeMap*/ )
destroy: ฦ’ () /*: Promise<ParseUser>*/ { var _this5 = this; for (var _len2 = arguments.length, args = new Array(_len2), _key5 = 0; _key5 < _len2; _key5++)
fetch: ฦ’ () /*: Promise<ParseUser>*/ { var _this6 = this; for (var _len3 = arguments.length, args = new Array(_len3), _key6 = 0; _key6 < _len3; _key6++)
fetchWithInclude: ฦ’ () /*: Promise<ParseUser>*/ { var _this7 = this; for (var _len4 = arguments.length, args = new Array(_len4), _key7 = 0; _key7 < _len4; _key7++)
getEmail: ฦ’ () /*: ?string*/ { var email = this.get('email'); if (email == null || typeof email === 'string')
getSessionToken: ฦ’ () /*: ?string*/ { var token = this.get('sessionToken'); if (token == null || typeof token === 'string')
getUsername: ฦ’ () /*: ?string*/ { var username = this.get('username'); if (username == null || typeof username === 'string')
isCurrent: ฦ’ ()
linkWith: ฦ’ (provider /*: any*/ , options /*: { authData?: AuthData }*/ ) /*: Promise<ParseUser>*/ { var _this2 = this; var saveOpts /*:: ?: FullOptions*/ = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; saveOpts.sessionToken = saveOpts.sessionToken || this.getSessionToken() || ''; var authType; if (typeof provider === 'string')
logIn: ฦ’ (options /*:: ?: FullOptions*/ ) /*: Promise<ParseUser>*/ { options = options || {}; var loginOptions = { usePost: true }; if (options.hasOwnProperty('useMasterKey'))
save: ฦ’ () /*: Promise<ParseUser>*/ { var _this4 = this; for (var _len = arguments.length, args = new Array(_len), _key4 = 0; _key4 < _len; _key4++)
setEmail: ฦ’ (email /*: string*/ )
setPassword: ฦ’ (password /*: string*/ )
setUsername: ฦ’ (username /*: string*/ )
signUp: ฦ’ (attrs /*: AttributeMap*/ , options /*:: ?: FullOptions*/ ) /*: Promise<ParseUser>*/ { options = options || {}; var signupOptions = {}; if (options.hasOwnProperty('useMasterKey'))
verifyPassword: ฦ’ ()
_cleanupAuthData: ฦ’ ()
_isLinked: ฦ’ (provider /*: any*/ ) /*: boolean*/ { var authType; if (typeof provider === 'string')
_linkWith: ฦ’ ()
_logOutWith: ฦ’ (provider /*: any*/ )
_logOutWithAll: ฦ’ ()
_preserveFieldsOnFetch: ฦ’ ()
_synchronizeAllAuthData: ฦ’ ()
_synchronizeAuthData: ฦ’ (provider /*: string*/ )
_unlinkFrom: ฦ’ (provider /*: any*/ , options /*:: ?: FullOptions*/ ) /*: Promise<ParseUser>*/ { var _this3 = this; return this.linkWith(provider, { authData: null }, options).then(function ()
_upgradeToRevocableSession: ฦ’ (options /*: RequestOptions*/ ) /*: Promise<void>*/ { options = options || {}; var upgradeOptions = {}; if (options.hasOwnProperty('useMasterKey'))
attributes: (...)
createdAt: (...)
updatedAt: (...)
[[Prototype]]: Object
add: ฦ’ ()
addAll: ฦ’ ()
addAllUnique: ฦ’ ()
addUnique: ฦ’ ()
attributes: (...)
clear: ฦ’ () /*: ParseObject | boolean*/ { var attributes = this.attributes; var erasable = {}; var readonly = ['createdAt', 'updatedAt']; if (typeof this.constructor.readOnlyAttributes === 'function')
clone: ฦ’ clone() /*: any*/ { var clone = new this.constructor(); if (!clone.className)
constructor: ฦ’ ParseObject(className /*: ?string | { className: string, [attr: string]: mixed }*/ , attributes /*:: ?: { [attr: string]: mixed }*/ , options /*:: ?: { ignoreValidation: boolean }*/ )
createdAt: (...)
decrement: ฦ’ (attr /*: string*/ , amount /*:: ?: number*/ ) /*: ParseObject | boolean*/ { if (typeof amount === 'undefined')
destroy: ฦ’ (options /*: RequestOptions*/ ) /*: Promise*/ { options = options || {}; var destroyOptions = {}; if (options.hasOwnProperty('useMasterKey'))
dirty: ฦ’ (attr /*:: ?: string*/ ) /*: boolean*/ { if (!this.id)
dirtyKeys: ฦ’ () /*: Array<string>*/ { var pendingOps = this._getPendingOps(); var keys = {}; for (var i = 0; i < pendingOps.length; i++)
equals: ฦ’ (other /*: mixed*/ ) /*: boolean*/ { if (this === other)
escape: ฦ’ (attr /*: string*/ ) /*: string*/ { var val = this.attributes[attr]; if (val == null)
existed: ฦ’ () /*: boolean*/ { if (!this.id)
exists: ฦ’ ()
fetch: ฦ’ (options /*: RequestOptions*/ ) /*: Promise*/ { options = options || {}; var fetchOptions = {}; if (options.hasOwnProperty('useMasterKey'))
fetchFromLocalDatastore: ฦ’ ()
fetchWithInclude: ฦ’ ()
get: ฦ’ ()
getACL: ฦ’ () /*: ?ParseACL*/ { var acl = this.get('ACL'); if (acl instanceof _ParseACL.default)
has: ฦ’ (attr /*: string*/ ) /*: boolean*/ { var attributes = this.attributes; if (attributes.hasOwnProperty(attr))
increment: ฦ’ (attr /*: string*/ , amount /*:: ?: number*/ ) /*: ParseObject | boolean*/ { if (typeof amount === 'undefined')
initialize: ฦ’ ()
isDataAvailable: ฦ’ ()
isNew: ฦ’ ()
isPinned: ฦ’ ()
isValid: ฦ’ ()
newInstance: ฦ’ () /*: any*/ { var clone = new this.constructor(); if (!clone.className)
op: ฦ’ (attr /*: string*/ ) /*: ?Op*/ { var pending = this._getPendingOps(); for (var i = pending.length; i--;)
pin: ฦ’ ()
pinWithName: ฦ’ ()
relation: ฦ’ (attr /*: string*/ ) /*: ParseRelation*/ { var value = this.get(attr); if (value)
remove: ฦ’ ()
removeAll: ฦ’ ()
revert: ฦ’ () /*: void*/ { var keysToRevert; for (var _len = arguments.length, keys = new Array(_len), _key2 = 0; _key2 < _len; _key2++)
save: ฦ’ (arg1 /*: ?string | { [attr: string]: mixed }*/ , arg2 /*: SaveOptions | mixed*/ , arg3 /*:: ?: SaveOptions*/ ) /*: Promise*/ { var _this = this; var attrs; var options; if ((0, _typeof2.default)(arg1) === 'object' || typeof arg1 === 'undefined')
set: ฦ’ (key /*: mixed*/ , value /*: mixed*/ , options /*:: ?: mixed*/ ) /*: ParseObject | boolean*/ { var changes = {}; var newOps = {}; if (key && (0, _typeof2.default)(key) === 'object')
setACL: ฦ’ ()
toJSON: ฦ’ (seen /*: Array<any> | void*/ , offline /*:: ?: boolean*/ ) /*: AttributeMap*/ { var _context; var seenEntry = this.id ? (0, _concat.default)(_context = "".concat(this.className, ":")).call(_context, this.id) : this; seen = seen || [seenEntry]; var json = {}; var attrs = this.attributes; for (var _attr5 in attrs)
toOfflinePointer: ฦ’ () /*: Pointer*/ { if (!this._localId)
toPointer: ฦ’ () /*: Pointer*/ { if (!this.id)
unPin: ฦ’ ()
unPinWithName: ฦ’ ()
unset: ฦ’ ()
updatedAt: (...)
validate: ฦ’ (attrs /*: AttributeMap*/ ) /*: ParseError | boolean*/ { if (attrs.hasOwnProperty('ACL') && !(attrs.ACL instanceof _ParseACL.default))
_clearPendingOps: ฦ’ (keysToClear /*:: ?: Array<string>*/ )
_clearServerData: ฦ’ ()
_finishFetch: ฦ’ (serverData /*: AttributeMap*/ )
_getDirtyObjectAttributes: ฦ’ () /*: AttributeMap*/ { var attributes = this.attributes; var stateController = _CoreManager.default.getObjectStateController(); var objectCache = stateController.getObjectCache(this._getStateIdentifier()); var dirty = {}; for (var _attr3 in attributes)
_getId: ฦ’ () /*: string*/ { if (typeof this.id === 'string')
_getPendingOps: ฦ’ ()
_getSaveJSON: ฦ’ () /*: AttributeMap*/ { var pending = this._getPendingOps(); var dirtyObjects = this._getDirtyObjectAttributes(); var json = {}; for (var attr in dirtyObjects)
_getSaveParams: ฦ’ () /*: SaveParams*/ { var method = this.id ? 'PUT' : 'POST'; var body = this._getSaveJSON(); var path = "classes/".concat(this.className); if (this.id)
_getServerData: ฦ’ ()
_getStateIdentifier: ฦ’ () /*: ParseObject | { id: string, className: string }*/ { if (singleInstance)
_handleSaveError: ฦ’ ()
_handleSaveResponse: ฦ’ (response /*: AttributeMap*/ , status /*: number*/ )
_migrateId: ฦ’ (serverId /*: string*/ )
_setExisted: ฦ’ (existed /*: boolean*/ )
_toFullJSON: ฦ’ ()
get attributes: ฦ’ ()
get createdAt: ฦ’ ()
get updatedAt: ฦ’ ()
[[Prototype]]: Object

try web3 = await Moralis.enableWeb3() and then see how you can get the ETH Address with web3