From f9d677fa7cbc2945d97ce0457e43a9b6565320d4 Mon Sep 17 00:00:00 2001 From: Warrick FitzGerald <40346010+WarrickFitz@users.noreply.github.com> Date: Tue, 2 May 2023 12:49:02 -0400 Subject: [PATCH 1/2] temp sign string settup --- src/Ethereum/ERC712Sign_typed_data_raw.ts | 137 ++++++++++++++++++++++ src/Ethereum/index.ts | 5 + src/index.ts | 78 +++++++++++- src/models/index.ts | 3 +- 4 files changed, 219 insertions(+), 4 deletions(-) create mode 100644 src/Ethereum/ERC712Sign_typed_data_raw.ts diff --git a/src/Ethereum/ERC712Sign_typed_data_raw.ts b/src/Ethereum/ERC712Sign_typed_data_raw.ts new file mode 100644 index 0000000..ee49e2f --- /dev/null +++ b/src/Ethereum/ERC712Sign_typed_data_raw.ts @@ -0,0 +1,137 @@ +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 ERC20ABI = [ + { + "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"} + ] + }; + + // , + // EIP712Domain: [ + // {name: "name", type: "string"}, + // {name: "version", type: "string"}, + // {name: "chainId", type: "uint256"}, + // {name: "verifyingContract", type: "address"}, + // ], + + var milsec_deadline = Date.now() / 1000 + 100; + console.log(milsec_deadline, "milisec"); + var deadline = parseInt(String(milsec_deadline).slice(0, 10)); + + // const deadline = 100; + const x = 5; + + const action : any = { + from: options.fromAccountName, + to: '0xE79e5dfbdaeb5bF5395A760FB0F7a5A71466234b', + contract: { + abi: ERC20ABI, + 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..8a427d1 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 @@ -52,6 +53,7 @@ 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 { Transaction } from '@open-rights-exchange/chain-js'; +import { SignString } from '../../chain-js/src/interfaces' var chain = PluginChainFactory([EOSPlugin, EthereumPlugin, AlorandPlugin], 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,73 @@ async function runTxn() { } +async function runSignString() { + try { + + 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 + }, + } + + const input2 = { + stringToSign: "Something to sign here" + } + + let signStringOptions = {signMethod : 'ethereum.sign-typed-data'} + // let signStringOptions = {signMethod : 'ethereum.personal-sign'} + // let signStringOptions = {signMethod : 'ethereum.eth-sign'} + + 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 runTxn() + await runSignString() 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 { From bfc076c84962274b543de46db7ccbd0809d1060e Mon Sep 17 00:00:00 2001 From: Gaetano Mondelli Date: Thu, 11 May 2023 08:45:07 +0100 Subject: [PATCH 2/2] fix: added supportTypedDataSignature and refactor to made excplicit different type of signatures for chain. TO-DO: adding missing signature parameters to other plugins --- src/Ethereum/ERC712Sign_typed_data_raw.ts | 13 +-- src/index.ts | 103 ++++++++++++---------- 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/Ethereum/ERC712Sign_typed_data_raw.ts b/src/Ethereum/ERC712Sign_typed_data_raw.ts index ee49e2f..5d33a17 100644 --- a/src/Ethereum/ERC712Sign_typed_data_raw.ts +++ b/src/Ethereum/ERC712Sign_typed_data_raw.ts @@ -8,7 +8,7 @@ import { ETHTxnTypes, IOptionBag, ITransactionBuilder, TransactionBuilderRespons // code=INVALID_ARGUMENT, version=hash/5.6.1) -export const ERC20ABI = [ +export const ERC712ABI = [ { "constant": true, "inputs": [] as any[], @@ -89,27 +89,18 @@ export class ERC712Sign_typed_data_raw_builder implements ITransactionBuilder { {name:"deadline", type:"uint"} ] }; - - // , - // EIP712Domain: [ - // {name: "name", type: "string"}, - // {name: "version", type: "string"}, - // {name: "chainId", type: "uint256"}, - // {name: "verifyingContract", type: "address"}, - // ], var milsec_deadline = Date.now() / 1000 + 100; console.log(milsec_deadline, "milisec"); var deadline = parseInt(String(milsec_deadline).slice(0, 10)); - // const deadline = 100; const x = 5; const action : any = { from: options.fromAccountName, to: '0xE79e5dfbdaeb5bF5395A760FB0F7a5A71466234b', contract: { - abi: ERC20ABI, + abi: ERC712ABI, method: 'executeSetIfSignatureMatch', //parameters: ["$eip712_v","$eip712_r","$eip712_s",options.fromAccountName, deadline, x], parameters: [0,"0x00","0x00",options.fromAccountName, deadline, x], diff --git a/src/index.ts b/src/index.ts index 8a427d1..5898ce8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -49,12 +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'; import { SignString } from '../../chain-js/src/interfaces' -var chain = PluginChainFactory([EOSPlugin, EthereumPlugin, AlorandPlugin], options.chainType, options.endpoints, options.chainSettings); +var chain = PluginChainFactory([EthereumPlugin], options.chainType, options.endpoints, options.chainSettings); async function runTxn() { @@ -202,52 +202,15 @@ async function runTxn() { } -async function runSignString() { - try { - 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 - }, - } +async function runSignMessage() { + try { - const input2 = { + const inputMessage = { stringToSign: "Something to sign here" } - let signStringOptions = {signMethod : 'ethereum.sign-typed-data'} - // let signStringOptions = {signMethod : 'ethereum.personal-sign'} - // let signStringOptions = {signMethod : 'ethereum.eth-sign'} - - var signString : SignString = null; - - signString = await chain.new.SignString(input, signStringOptions) + signString = await chain.new.SignString(inputMessage) let validateResult = await signString.validate(); if(!validateResult.valid) { console.log('Oh no, it was not valid') @@ -258,6 +221,54 @@ async function runSignString() { 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) { @@ -267,8 +278,8 @@ async function runSignString() { ;(async () => { if(chain) { - //await runTxn() - await runSignString() + await runTxn() + await runSignMessage() process.exit() } })() \ No newline at end of file