Hi, can anyone here help me figure out how to crea...
# javascript
l
Hi, can anyone here help me figure out how to create an instance of a js
web3.eth.Contract
? Forgive me if this is a stupid question, as I am not the most familiar with js. I am more used to standard kotlin/OOP. I've figured out that an instance of
web3.eth.Contract
must be created where
web3
must be an actual instance of a
Web3
class (created
new Web3(...)
) So I cannot simply create a contract instance by calling
new Web3.eth.Contract(...)
For example
js("""new (new Web3(window.ethereum)).eth.Contract(JSON.parse('...'), '...' )""")
will create a valid instance of a
Contract
But, when I attempt to create an instance of a kotlin defined contract:
Copy code
@JsModule("web3-eth-contract")
@JsNonModule
open external class Contract constructor(jsonInterface: Array<AbiItem>, address: String, options: ContractOptions)
by calling
Copy code
val contract = Contract (jsonInterface = abis as Array<AbiItem>, address = adr)
An instance of
Contract
IS created successfully, however it is worthless because the created contract seems to rely on a parent instance of
Web3
, (like in the first example I mentioned). How can I create a Contract class in kotlin, that is instantiated in the same way as
js("""new (new Web3(window.ethereum)).eth.Contract(JSON.parse('...'), '...' )""")
?
b
l
@Big Chungus that's somewhat helpful. But there's no examples of defining function variables like the contract function variable here: https://github.com/ChainSafe/web3.js/blob/5df6818ee4a0a30fb64dd3e94d97964826489b7f/packages/web3-eth/src/index.js
Any idea how to handle that?
b
That's because you should be looking into that package's types https://github.com/ChainSafe/web3.js/blob/1.x/packages/web3-eth/types/index.d.ts
should look something like this
Copy code
external class Eth {
  val Contract: dynamic
{
You can replace dynamic type with your own external interface/class defining Contract type shape
Js doesn't actually have classes, it's just a syntactic sugar over function, that's why it's so confusing when compiled down to early es versions
l
Okay thanks for the tip! @Big Chungus I'll see what I can do
@Big Chungus so i tried defining Contract as
Copy code
external class Eth {
    val Contract: (Array<AbiItem>, String) -> Contract
}
But I get the error:
Error: Please use the "new" keyword to instantiate a web3.eth.Contract() object!
So I think I'm getting closer. But, not sure how to handle the new keyword. Any ideas?
b
That's because Eth class in js has no such function. Have a better look at .d.ts structure
l
@Big Chungus I finally got something working kinda. Didn't realize I could actually use variables in
js(...)
previously I had only tried using variables by prepending
$
to the varable names inside
js(...)
and that doesn't work
Copy code
external class Eth {
...
    val Contract: (Array<AbiItem>, String, ContractOptions?) -> Contract
...
}
Copy code
val abis : Array<AbiItemImpl> = ...
    val adr  = "..."

    val contractFunction = web3Wrapper.web3.eth.Contract
    val contract = js("""new contractFunction(abis, adr)""" )
But, is there anyway I can avoid using resorting to using
js(...)
and use actual kotlin code to instantiate the Contract?
b
Yes, by declaring your externals properly
l
Do you have any examples? I've tried everything I can think of. I don't understand how you are "properly" supposed to declare the contract function inside the Eth class so that it would be essentially instantiated as an inner class? (inner classes aren't allowed in external classes, I checked) @Big Chungus
I noticed that the contract function inside Eth is different that the contract function from 'web3-eth-contract' so I tried wrapping it like this:
Copy code
external class Eth {
...
    val Contract: ContractFunction0

    interface ContractFunction0 {
        @nativeInvoke
        fun invoke(a: Array<AbiItem>, b: String?, c: ContractOptions?): web3.eth.Contract
    }
...
}
Copy code
val abis : Array<AbiItemImpl> = ...
    val adr  = "..."

    val contract = web3Wrapper.web3.eth.Contract.invoke(abis, adr, null)
However I still get the same result
Error: Please use the "new" keyword to instantiate a web3.eth.Contract() object!
b
Ok here goes. Firstly, in Eth class, that
Contract
property is referring to
Contract
class constructor, not just a function returning a
Contract
. Unfortunatelly, currently there's no way to express constructor reference types in K/JS yet, so you'll need to just wrap
Constructor
class from web3-eth-contract module separately and use that to build your Contracts. Eth class is not needed to build an instance of the contract. The constructor reference there is just for convenience.
l
I am able to create a contract instance on it's own, without an instance of Eth. But, then I run into the problem where's it's not actually useable for my purposes. It will throw errors when I attempt to call its methods.
Not on my computer rn. But I can post the specific errors later