Skip to content

Commit c659fc7

Browse files
committed
feat: Allow complex input types for ethereum:transaction and ethereum:call args
This commit allows complex input types for function inputs, such as arrays or structs. When ts:struct is used as an argument input, it's local-ref is used to get the correct input type from the ABI supplied within the contract definition. Complex arguments can then be set using setProps() within the JS card.
1 parent 207c2ed commit c659fc7

File tree

4 files changed

+34
-11
lines changed

4 files changed

+34
-11
lines changed

javascript/engine-js/src/TokenScript.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -765,9 +765,9 @@ export class TokenScript {
765765
}], ["bool"]
766766
);
767767
} catch (e) {
768-
768+
769769
}
770-
770+
771771
return isAuthorised;
772772
}
773773

@@ -784,24 +784,24 @@ export class TokenScript {
784784

785785
// TODO: confirm with James exact use cases of having multiple address in a contract element
786786
const chain = this.getCurrentTokenContext()?.chainId ?? await wallet.getChain();
787-
const contract = transInfo.contract.getAddressByChain(chain, true);
787+
const contractAddr = transInfo.contract.getAddressByChain(chain, true);
788788

789789
// If validation callback returns false we abort silently
790-
if (!await this.transactionValidator.validateContract(chain, contract.address, transInfo.contract, transInfo.function))
790+
if (!await this.transactionValidator.validateContract(chain, contractAddr.address, transInfo.contract, transInfo.function))
791791
return false;
792792

793793
const errorAbi = transInfo.contract.getAbi("error");
794794

795795
const ethParams = [];
796796

797797
for (let i in transInfo.args){
798-
ethParams.push(await transInfo.args[i].getEthersArgument(this.getCurrentTokenContext()))
798+
ethParams.push(await transInfo.args[i].getEthersArgument(this.getCurrentTokenContext(), transInfo.function, transInfo.contract))
799799
}
800800

801801
const ethValue = transInfo.value ? await transInfo?.value?.getValue(this.getCurrentTokenContext()) : null;
802802

803803
listener({status: 'started'});
804804

805-
return await wallet.sendTransaction(contract.chain, contract.address, transInfo.function, ethParams, [], ethValue, waitForConfirmation, listener, errorAbi);
805+
return await wallet.sendTransaction(contractAddr.chain, contractAddr.address, transInfo.function, ethParams, [], ethValue, waitForConfirmation, listener, errorAbi);
806806
}
807807
}

javascript/engine-js/src/tokenScript/Attribute.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ export class Attribute {
223223
const ethParams = [];
224224

225225
for (let i in args) {
226-
ethParams.push(await args[i].getEthersArgument(tokenContext))
226+
ethParams.push(await args[i].getEthersArgument(tokenContext, func, contract))
227227
}
228228

229229
resultValue = await wallet.call(contractAddr.chain, contractAddr.address, func, ethParams, outputTypes);

javascript/engine-js/src/tokenScript/Transaction.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {Argument} from "./data/function/Argument";
55
import {Attributes} from "./Attributes";
66
import {EthUtils} from "../ethereum/EthUtils";
77

8-
interface ITransactionInfo {
8+
export interface ITransactionInfo {
99
as: string,
1010
contract: Contract,
1111
contractName: string,

javascript/engine-js/src/tokenScript/data/function/Argument.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {Attributes} from "../../Attributes";
33
import {EthUtils, IEthersArgument} from "../../../ethereum/EthUtils";
44
import {AbstractDependencyBranch} from "../AbstractDependencyBranch";
55
import {ITokenContextData} from "../../../tokens/ITokenContextData";
6+
import {Contract} from "../../Contract";
67

78
export interface IArgument {
89
type: string;
@@ -30,10 +31,14 @@ export class Argument extends AbstractDependencyBranch implements IArgument {
3031
this.localRef = argDef.getAttribute("local-ref");
3132
}
3233

34+
public getName(){
35+
return this.localRef ?? this.ref;
36+
}
37+
3338
/**
3439
* Get the ethers argument data for this argument
3540
*/
36-
public async getEthersArgument(tokenContext: ITokenIdContext, name: string = ""){
41+
public async getEthersArgument(tokenContext: ITokenIdContext, functionName: string, contract: Contract){
3742

3843
let overrideValue;
3944

@@ -43,7 +48,7 @@ export class Argument extends AbstractDependencyBranch implements IArgument {
4348
}
4449

4550
let arg: Partial<IEthersArgument> = {
46-
name,
51+
name: this.getName(),
4752
value: overrideValue ?? await this.getValue(tokenContext)
4853
};
4954

@@ -66,7 +71,25 @@ export class Argument extends AbstractDependencyBranch implements IArgument {
6671
break;
6772

6873
default:
69-
throw new Error("Struct encoding is not defined for " + this.ref + " attribute.");
74+
75+
const abi = contract.getAbi("function", functionName);
76+
77+
console.log("ABI: ", abi);
78+
79+
if (abi.length){
80+
const abiArg = abi[0].inputs.find((arg: any) => {
81+
return arg.name == this.localRef || arg.name == this.ref;
82+
});
83+
84+
if (abiArg){
85+
arg.type = abiArg.type;
86+
arg.internalType = abiArg.internalType;
87+
arg.components = abiArg.components;
88+
break;
89+
}
90+
}
91+
92+
throw new Error(`Struct or ABI encoding is not defined for ${this.localRef ?? this.ref} arg in contract ${contract.getName()} method ${functionName}`);
7093
}
7194
} else {
7295
arg.type = this.type;

0 commit comments

Comments
 (0)