defold / asset-portal

List of Defold assets, libraries and extensions
178 stars 33 forks source link

In-app purchasing by cryptocurrency #207

Closed bdshahab closed 2 months ago

bdshahab commented 2 months ago

Optionally also attach two images In-app purchasing by cryptocurrency-hero.[png|jpg] (max 2400x666) and In-app purchasing by cryptocurrency-thumb.[png|jpg] (max 580x380). { "name": "In-app purchasing by cryptocurrency", "description": "A simple way to enable in-app purchases using cryptocurrencies.\n\n", "license": "MIT", "author": "bdshahab", "library_url": "", "project_url": "https://github.com/bdshahab/iap_defold", "forum_url": "", "website_url": "https://lnk.bio/bdshahab", "platforms": [ "android", "ios", "macos", "windows", "linux" ], "tags": [ "monetization", "sample project", "template projects" ], "images": { "hero": "", "thumb": "" } }

bdshahab commented 2 months ago

I published this one for Godot, but you didn't accept it for Defold! Because it wasn't a plugin. https://godotengine.org/asset-library/asset/3158

britzl commented 2 months ago

Thank you for submitting an updated asset. I still don't really see that this is a plugin that someone can add as a library dependency to pay using crypto. How is someone supposed to use this in their own project?

I decided to try the project but got an error:

ERROR:SCRIPT: IAP/payment.gui_script:364: attempt to perform arithmetic on local 'number' (a string value)
stack traceback:
  IAP/payment.gui_script:364: in function <IAP/payment.gui_script:357>

I'm also a bit confused by the https://raw.githubusercontent.com/bdshahab/iap_defold/main/key_data.txt. GitHub will rate limit access to such a file and if many users at once request the same file it might happen that the access is denied.

I also noticed that you are using global functions almost everywhere. This is not recommended as there's a risk that the global function names of your code conflicts with other global function names.

I also noticed that you are doing a lot of regex matching against html. Is there really not REST API or similar where you can get prices and validate transactions in a more programmatic fashion?

bdshahab commented 2 months ago
  1. The "number" variable becomes a real number by the "get_just_number" function 3 lines before that warning message!

  2. The "key_data.txt" file is used to update key data to find necessary data for price, validation, etc. I hope GitHub doesn't limit access to that! I want to present a free alternative to the official, non-free methods.

  3. I set a global variable(user_bought) to indicate if the user paid or not, and that's necessary to access everywhere, too. Some functions have to be global in Lua! I always tried to use local unless it's impossible. For example, if I change the "get_just_number" function to local, "Defold" shows an error!

  4. I used regex matching to search and find data very easily and update it by that key_data file.

  5. It's a suggestion program and if you could change it to something more efficient and still be free and available for everyone, that's OK to change it. I don't say my program is perfect and flawless.

britzl commented 2 months ago
  1. The "number" variable becomes a real number by the "get_just_number" function 3 lines before that warning message!

No. It is not a warning message. It is a Lua error. Your function get_just_number() fails to convert the value to a number and instead returns a string. And you can't use a string to perform arithmetic on line 364 (https://github.com/bdshahab/iap_defold/blob/main/IAP/payment.gui_script#L364)

2. I hope GitHub doesn't limit access to that! I want to present a free alternative to the official, non-free methods.

It is likely to be fine, but I wanted you to be aware of it.

3. Some functions have to be global in Lua! I always tried to use local unless it's impossible. For example, if I change the "get_just_number" function to local, "Defold" shows an error!

The best practice is to not use global functions. The reason why you get an error in the case of get_just_number() is that if you want to make the function local it has to be declared before it is used (ie closer to the top of the file). If you declare a local function after it is used it will not be accessible.

4. I used regex matching to search and find data very easily and update it by that key_data file.

It works now, but what if https://cryptorank.io/price/ changes their page layout so that you can't match it anymore?

5. It's a suggestion program and if you could change it to something more efficient and still be free and available for everyone, that's OK to change it. I don't say my program is perfect and flawless.

My very strong recommendation would be to use a public API to get exchange rates. A very quick search found these service:

Example Defold code to get ETH to USD:

function init(self)
    local URL = "https://api.api-ninjas.com/v1/cryptoprice?symbol=ETHUSD"
    local headers = {
        ["X-Api-Key"] = "your-api-ninja-key"
    }
    http.request(URL, "GET", function(self, _, response)
        pprint(response) -- {"symbol": "ETHUSD", "price": "1595.49000000", "timestamp": 1721723437}
        if response.status >= 200 and response.status < 400 then
            local result = json.decode(response.response)
            print(tonumber(result.price)) -- 1595.49
        else
            print("Error", response.status)
        end
    end, headers)
end

There's also API services to get transactions, for instance https://docs.blockdaemon.com/reference/gettxbyhash

    local URL = "https://svc.blockdaemon.com/universal/v1/ethereum/mainnet/tx/" .. tx

    local headers = {
        ["accept"] = "application/json",
        ["X-API-Key"] = "2go1YqUcuAr4WZ2-3WgSD3c7qpatZqQuNWhTVBldKZnTSUtw"
    }

    http.request(URL, "GET", function(self, _, response)
        pprint(response)
        --[[ {"id":"0x94f69e5bccbe26102e32a8c60d5321940542c14479bcc0497574d79755e941b6","block_id":"0xa8cc73c888d930964307a5ecd973cfe03db26d444c086d69498576ef06186eab","date":1721724479,"status":"completed","num_events":2,"meta":{"index":303,"to":"0x4675C7e5BaAFBFFbca748158bEcBA61ef3b0a263"},"block_number":20368132,"confirmations":17,"events":[{"id":"0x94f69e5bccbe26102e32a8c60d5321940542c14479bcc0497574d79755e941b6-fee","transaction_id":"0x94f69e5bccbe26102e32a8c60d5321940542c14479bcc0497574d79755e941b6","type":"fee","denomination":"ETH","source":"0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5","meta":{"base_fee":4761517915,"fee_burned":99991876215000,"gas_limit":21000,"gas_price":4761517915,"gas_used":21000},"date":1721724479,"amount":99991876215000,"decimals":18},{"id":"0x94f69e5bccbe26102e32a8c60d5321940542c14479bcc0497574d79755e941b6-470","transaction_id":"0x94f69e5bccbe26102e32a8c60d5321940542c14479bcc0497574d79755e941b6","type":"transfer","denomination":"ETH","source":"0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5","destination":"0x4675C7e5BaAFBFFbca748158bEcBA61ef3b0a263","meta":null,"date":1721724479,"amount":37279098734118659,"decimals":18}]} ]]
        if response.status >= 200 and response.status < 400 then
            local result = json.decode(response.response)
            pprint(result)
        else
            print("Error", response.status)
        end
    end, headers)
bdshahab commented 2 months ago
  1. function "get_just_number" returns a number and sometimes a string! That was my mistake! Good point. Thanks for your help. I corrected it now. But for me, it never returned any error before! Although I fixed it now.

  2. My functions in this program are very connected to each other and also related to some key variables! So it's not easy to separate them or just put them on top of one another! That could lead to chain problems for other functions!

  3. If "https://cryptorank.io/price" changes its page layout, I update the _keydata.txt file to use another Regex or even another website. That's my strategy for using it!

  4. You suggested some websites and I appreciate you, but "api-ninjas.com" is not free! And two other websites you suggested, are not accessible in my country (Iran)! So, since my first ambition to build this program was to present an income method for everyone in any country, this isn't good for me to use it.

  5. I used the part of the code you suggested about the correct internet connection! Thank you again! In function connection_status: (code >= 200 and code < 400)