diff --git a/src/Ethereum/ERC712Sign_typed_data_raw.ts b/src/Ethereum/ERC712Sign_typed_data_raw.ts new file mode 100644 index 0000000..5d33a17 --- /dev/null +++ b/src/Ethereum/ERC712Sign_typed_data_raw.ts @@ -0,0 +1,128 @@ +import { Chain, Transaction } from "@open-rights-exchange/chain-js"; +import { HelpersEthereum } from "@open-rights-exchange/chain-js-plugin-ethereum"; +import { ETHTxnTypes, IOptionBag, ITransactionBuilder, TransactionBuilderResponse } from "src/models"; + +// There was an error: Error: ambiguous primary types or unused types: "MyTypeA", +// "EIP712Domain" (argument="types", value={"MyTypeA":[{"name":"sender","type":"address"},{"name":"x","type":"uint"},{"name":"deadline","type":"uint"}], +// "EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}]}, +// code=INVALID_ARGUMENT, version=hash/5.6.1) + + +export const ERC712ABI = [ + { + "constant": true, + "inputs": [] as any[], + "name": "get", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + } + ], + "name": "executeSetIfSignatureMatch", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] + + +export class ERC712Sign_typed_data_raw_builder implements ITransactionBuilder { + async build(chain: Chain, options: IOptionBag, txnType: ETHTxnTypes): Promise { + + let moreOptions = {signMethod : 'etherum.sign-typed-data'} + let extOptions = {...options.defaultTransactionOptions, ...moreOptions} + + var transaction : Transaction = await chain.new.Transaction(extOptions) + + const eip712_domain = { + name: "name", + version: "1", + verifyingContract: "0xB6Fa4E9B48F6fAcd8746573d8e151175c40121C7", + chainId: 1, + }; + + const eip712_types = { + MyTypeA: [ + {name:"sender",type:"address"}, + {name:"x",type:"uint"}, + {name:"deadline", type:"uint"} + ] + }; + + var milsec_deadline = Date.now() / 1000 + 100; + console.log(milsec_deadline, "milisec"); + var deadline = parseInt(String(milsec_deadline).slice(0, 10)); + + const x = 5; + + const action : any = { + from: options.fromAccountName, + to: '0xE79e5dfbdaeb5bF5395A760FB0F7a5A71466234b', + contract: { + abi: ERC712ABI, + method: 'executeSetIfSignatureMatch', + //parameters: ["$eip712_v","$eip712_r","$eip712_s",options.fromAccountName, deadline, x], + parameters: [0,"0x00","0x00",options.fromAccountName, deadline, x], + eip712: { + version: 4, + types: eip712_types, + primaryType: "MyTypeA", + domain: eip712_domain, + message: { + sender: options.fromAccountName, + x, + deadline + }, + parameterSubstitution: { + v: 0, + r: 1, + s: 2 + } + } + }, + } + + return {transaction, action} + } +} \ No newline at end of file diff --git a/src/Ethereum/index.ts b/src/Ethereum/index.ts index 569c317..8618b8d 100644 --- a/src/Ethereum/index.ts +++ b/src/Ethereum/index.ts @@ -9,6 +9,7 @@ import { Multisig } from './Multisig' import { ERC20TransferFrom_raw } from './ERC20TransferFrom_raw' import { ERC1155TransferFrom_template_Builder } from './ERC1155TransferFrom_template' import { ERC1155SafeTransferFrom_raw_Builder } from './ERC1155SafeTransferFrom_raw' +import { ERC712Sign_typed_data_raw_builder } from './ERC712Sign_typed_data_raw' export class EthereumTransactionBuilder implements ITransactionBuilder { @@ -51,6 +52,10 @@ export class EthereumTransactionBuilder implements ITransactionBuilder { response = await new ERC1155SafeTransferFrom_raw_Builder().build(chain, options, txnType); break } + case(ETHTxnTypes.Erc712Sign_typed_data_raw): { + response = await new ERC712Sign_typed_data_raw_builder().build(chain, options, txnType); + break + } default: { Errors.throwNewError("txnType " + txnType.toString() + " is not yet implemented") } diff --git a/src/index.ts b/src/index.ts index 824e2d2..5898ce8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,7 +13,8 @@ import { AlgorandTransactionBuilder } from './Algorand' // let chainId = "eth", networkId = "goerli", doMSIG = false, txnType = ETHTxnTypes.ERC20TransferFrom_raw // let chainId = "matic", networkId = "polygon_mumbai", doMSIG = false, txnType = ETHTxnTypes.TokenTransfer // let chainId = "avalanche", networkId = "fuji", doMSIG = false, txnType = ETHTxnTypes.TokenTransfer -let chainId = "avalanche", networkId = "mainnet", doMSIG = false, txnType = ETHTxnTypes.TokenTransfer +//let chainId = "avalanche", networkId = "mainnet", doMSIG = false, txnType = ETHTxnTypes.TokenTransfer +let chainId = "eth", networkId = "goerli", doMSIG = false, txnType = ETHTxnTypes.Erc712Sign_typed_data_raw // let chainId = "telosevm", networkId = "testnet", doMSIG = false, txnType = ETHTxnTypes.TokenTransfer // let chainId = "telosevm", networkId = "mainnet", doMSIG = false, txnType = ETHTxnTypes.TokenTransfer @@ -48,11 +49,12 @@ const options: IOptionBag = { -- Note that the 1st parameter passed to PluginChainFactory is an array of plugins loaded by the user. */ import { PluginChainFactory } from '@open-rights-exchange/chain-js' -import { Plugin as EOSPlugin} from '@open-rights-exchange/chain-js-plugin-eos' +// import { Plugin as EOSPlugin} from '@open-rights-exchange/chain-js-plugin-eos' import { Plugin as EthereumPlugin, ModelsEthereum, HelpersEthereum, GnosisSafeMultisigPlugin, EthereumTransaction, MultisigPlugin} from '@open-rights-exchange/chain-js-plugin-ethereum' -import { Plugin as AlorandPlugin} from '@open-rights-exchange/chain-js-plugin-algorand' +// import { Plugin as AlgorandPlugin} from '@open-rights-exchange/chain-js-plugin-algorand' import { Transaction } from '@open-rights-exchange/chain-js'; -var chain = PluginChainFactory([EOSPlugin, EthereumPlugin, AlorandPlugin], options.chainType, options.endpoints, options.chainSettings); +import { SignString } from '../../chain-js/src/interfaces' +var chain = PluginChainFactory([EthereumPlugin], options.chainType, options.endpoints, options.chainSettings); async function runTxn() { @@ -70,7 +72,13 @@ async function runTxn() { //If txnType is tokentransfer we use our generic code. Else we setup the transaction using one of the custom if(txnType.toString() == "tokentransfer") { - transaction = await chain.new.Transaction(options.defaultTransactionOptions); + console.log('options.defaultTransactionOptions') + console.log(options.defaultTransactionOptions) + let moreOptions = {signMethod : 'etherum.sign-typed-data'} + let extOptions = {...options.defaultTransactionOptions, ...moreOptions} + console.log('extOptions') + console.log(extOptions) + transaction = await chain.new.Transaction(extOptions); var genericValueTransfer = { fromAccountName: options.fromAccountName, @@ -194,9 +202,84 @@ async function runTxn() { } + +async function runSignMessage() { + try { + + const inputMessage = { + stringToSign: "Something to sign here" + } + + signString = await chain.new.SignString(inputMessage) + let validateResult = await signString.validate(); + if(!validateResult.valid) { + console.log('Oh no, it was not valid') + console.log(validateResult.message) + console.log(validateResult.example) + } else { + let result = await signString.sign([options.privateKey_singleSign]); + console.log(result) + } + + if(chain.supportsTypedDataSignature){ + let signStringOptions = {signMethod : 'ethereum.sign-typed-data'} + const eip712_domain = { + name: "name", + version: "1", + verifyingContract: "0xB6Fa4E9B48F6fAcd8746573d8e151175c40121C7", + chainId: 1, + }; + + const eip712_types = { + MyTypeA: [ + {name:"sender",type:"address"}, + {name:"x",type:"uint"}, + {name:"deadline", type:"uint"} + ] + }; + + var milsec_deadline = Date.now() / 1000 + 100; + console.log(milsec_deadline, "milisec"); + var deadline = parseInt(String(milsec_deadline).slice(0, 10)); + const x = 5; + + const input = { + version: 4, + types: eip712_types, + primaryType: "MyTypeA", + domain: eip712_domain, + message: { + sender: options.fromAccountName, + x, + deadline + }, + } + + var signString : SignString = null; + + signString = await chain.new.SignString(input, signStringOptions) + let validateResult = await signString.validate(); + if(!validateResult.valid) { + console.log('Oh no, it was not valid') + console.log(validateResult.message) + console.log(validateResult.example) + } else { + let result = await signString.sign([options.privateKey_singleSign]); + console.log(result) + } + } + + + + } catch(error) { + console.log("There was an error: " + error); + } +} + ;(async () => { if(chain) { await runTxn() + await runSignMessage() process.exit() } })() \ No newline at end of file diff --git a/src/models/index.ts b/src/models/index.ts index 2cbb178..ec0adb8 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -10,7 +10,8 @@ export enum ETHTxnTypes { Multisig = "multisig", ERC20TransferFrom_raw = "erc20transferfrom_raw", Erc1155TransferFrom_template = "erc1155transferfrom_template", - Erc1155SafeTransferFrom_raw = "erc1155safeTransferFrom_raw" + Erc1155SafeTransferFrom_raw = "erc1155safeTransferFrom_raw", + Erc712Sign_typed_data_raw = "erc712sign_typed_data_raw" } export enum EOSTxnTypes {