Code Monkey home page Code Monkey logo

safe-core-sdk's People

Contributors

clemsos avatar cmdzro avatar danisomoza avatar dasanra avatar datradito avatar de33 avatar dependabot[bot] avatar einaralex avatar germartinez avatar iamacook avatar ioloie avatar itinance avatar jfschwarz avatar katspaugh avatar kyosyun avatar leonardotc avatar mmv08 avatar octavioamu avatar pradel avatar prestwich avatar raymondfeng avatar rellfy avatar rmeissner avatar rudolfs avatar schmanu avatar sirvar avatar tmjssz avatar usame-algan avatar vigan-abd avatar yagopv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

safe-core-sdk's Issues

createTransaction throws an error if the actual transaction fails

Description

safeSdk.createTransaction(contractInteractionTransaction) will fail if the actual transaction will revert

Environment

  • Safe Core SDK version: 1.0.0

Steps to reproduce

Create a failing transaction

Expected result

  1. This is documented
  2. Should there be a flag that allows skipping the check?

Build Multi-Step Gnosis Safe Transactions without Tx Service

Context / issue

I'd like to iteratively build complex multi-step Gnosis Safe transactions and safely preview their side effects from forked mainnet without having to rely on the transaction service.

In general I'd like to use the multisig signer within the safe-ethers-provider directory as the signer for the contracts that I'll be interacting with. This interactions.ts is a good example of the way I'd like to interact with the contracts with out having to construct a transaction similar to what is displayed here.

Another example of a similar feature can be seen here.

Why is this feature needed?

safe-ethers-provider is a great too for building complex transactions in an easy and simple way. However, the reliance on the transaction service limits the versatility of the tool and makes it difficult to simulate on a forked network.

Proposed solution

  • Allow for the building of complex multi-step Gnosis Safe Transactions that are queued up to be submitted.
  • Remove reliance on the transaction service when simulating the batch transactions. This can likely be achieved by separating out the transaction service until it's necessary to be submitted; the submission to the tx service should be both the last and separate step.

Alternatives

Please add a clear and concise description of any alternative solutions or features you have considered.
A solution closely resembling the desired functionality

Additional context

N/A

Allow EIP-3770 chain-specific addresses

Overview

We are pushing to implement EIP-3770 address references, which include a prefixed chain id before an address. We need to allow users to input addresses with a chain prefix.

image

Goals

  • Accept/validate EIP-3770 address input.

Requirements

  • Modify inputs/validation to allow EIP-3770 address formats.
  • Validate networks against this map. (A service will likely be created for this but it is acceptable to do this client-side in the web app.)
  • Validate that prefixed addresses match those of the current network.

Links

Kick off notes

Add /all-transactions to safe-service-client

Context / issue

There appears to be no support for all the GET ​/safes​/{address}​/all-transactions​/ endpoint outlined in the swagger

Proposed solution

Add a safeService.getAllTransactions(safeAddress) function

Additional context

It is needed to build functionality similar to the History tab seen in the gnosis safe app. Without it, there is no straightforward way to get an overview of the safe

Safe.create throws all sorts of errors if you provide contract address that is not a safe

Description

Safe user reported the following problem:

I try to Safe.create() to an existing contract that is NOT a safe, it throws all sorts of connection issues instead of a nice error > message. Basically I need a way of checking if an address is a safe. It works fine if the provided address is an EOA

Environment

  • Safe Core SDK version: latest at the moment of writing the issue

Steps to reproduce

Call safe.create() with a contract address that is not a Safe

Expected result

A good error message and a method to check if an address is a safe

Additional context

[  Error: missing revert data in call exception (error={"reason":"processing response error","code":"SERVER_ERROR","body":"{\"jsonrpc\":\"2.0\",\"id\":49,\"error\":{\"code\":-32000,\"message\":\"execution reverted\"}}"
,  "error":{"code":-32000},"requestBody":"{\"method\":\"eth_call\",\"params\":[{\"from\":\"0xb64ff7a4a33acdf48d97dab0d764afd0f6176882\",\"to\":\"0x9fde8abd74998779fe90383e74666ea7387d4bb1\",\"data\":\"0x2f54bf6e0000000
0  0000000000000000b64ff7a4a33acdf48d97dab0d764afd0f6176882\"},\"latest\"],\"id\":49,\"jsonrpc\":\"2.0\"}","requestMethod":"POST","url":"https://rinkeby.infura.io/v3/"}, data="0x", code=
C  ALL_EXCEPTION, version=providers/5.4.3)

  - index.js:199 Logger.makeError
    [synthetix]/[@ethersproject]/logger/lib/index.js:199:21

  - index.js:208 Logger.throwError
    [synthetix]/[@ethersproject]/logger/lib/index.js:208:20

  - json-rpc-provider.js:76 checkError
    [synthetix]/[@ethersproject]/providers/lib/json-rpc-provider.js:76:16

  - json-rpc-provider.js:633 JsonRpcProvider.<anonymous>
    [synthetix]/[@ethersproject]/providers/lib/json-rpc-provider.js:633:47

  - json-rpc-provider.js:48 step
    [synthetix]/[@ethersproject]/providers/lib/json-rpc-provider.js:48:23

  - json-rpc-provider.js:29 Object.throw
    [synthetix]/[@ethersproject]/providers/lib/json-rpc-provider.js:29:53

  - json-rpc-provider.js:21 rejected
    [synthetix]/[@ethersproject]/providers/lib/json-rpc-provider.js:21:65

  - task_queues.js:95 processTicksAndRejections
    internal/process/task_queues.js:95:5

More details on the purpose of each package/SDK and its intended use

Hey, thanks for these great SDK libs!
I've been wondering what the specific purpose of each of the packages is as listed in https://github.com/gnosis/safe-core-sdk#packages

Especially I had hard time figuring out how to add delegates using gnosis-core-sdk. It occurred that use case is supported in service client package.

So, could you

  1. improve the details about purpose of each of the packages
  2. provide an example use cases and limitations
  3. maybe a rough sketch of the roadmap of what you plan for each of the SDKs.

That would help consume the libs with less confusion.

Add rejectTransaction method to the Safe Core SDK

The developer would call safeSdk.rejectTransaction(safeTransaction) to propose the rejection of a transaction. Similar to signTransaction but saving the rejection signatures associated to the transaction.

Contract deployment execution fails in one of the internal transactions

Hey! I successfully did proposal+approval+execution of an ETH transfer transaction.
But I keep failing with contract deployment one.
The code:

import {BigNumber, ethers, providers, Signer} from 'ethers'
import Safe, {EthersAdapter} from '@gnosis.pm/safe-core-sdk'
import SafeServiceClient from "@gnosis.pm/safe-service-client";
import {SafeTransactionDataPartial} from '@gnosis.pm/safe-core-sdk-types'
import {getDeployTx} from "../../src/execute/getDeployTx";
import {SimpleContract} from "../fixtures/exampleArtifacts";
import {AbiSymbol, Bytecode} from "../../src/symbols";

const config = {
  txServiceUri: 'https://safe-transaction.rinkeby.gnosis.io', // Rinkeby Gnosis Transaction Service URI
  infuraApiKey: 'xxxxxxx'
  ethNetworkName: 'rinkeby', // in TT we test Gnosis Safes in Rinkeby
  ttSafe: '0x8772CD484C059EC5c61459a0abb5A45ece16701f', // TT Rinkeby Test Safe
  owner: { // one of many owners of the TT Test Safe
    address: '0x4a70cc993A25F0D57Fb37B8E8D5C7CcC0B24Cd7d',
    privateKey: process.env.OWNER_PRIVATE_KEY as string
  },
  delegate: { // one of the delegates
    address: '0x48A1B8fF5cEa06D95187f9A1B528D0c90554A179',
    privateKey: process.env.DELEGATE_PRIVATE_KEY as string
  }
}

// based on https://docs.gnosis-safe.io/build/sdks/core-sdk
describe("Gnosis Safe as multisig contract deployment service in Rinkeby", () => {
  let safeServiceClient: SafeServiceClient
  let owner: Signer
  let delegate: Signer
  let safeByOwner: Safe // safe managed via the owner account
  let safeByDelegate: Safe // safe managed via the delegate account

  beforeEach(async () => {
    safeServiceClient = new SafeServiceClient(config.txServiceUri)
    const web3Provider = new providers.InfuraProvider(config.ethNetworkName, config.infuraApiKey)
    owner = new ethers.Wallet(config.owner.privateKey, web3Provider)
    delegate = new ethers.Wallet(config.delegate.privateKey, web3Provider)
    safeByOwner = await Safe.create({
      ethAdapter: new EthersAdapter({ethers, signer: owner}),
      safeAddress: config.ttSafe
    })
    await safeByOwner.connect({})
    safeByDelegate = await Safe.create({
      ethAdapter: new EthersAdapter({ethers, signer: delegate}),
      safeAddress: config.ttSafe
    })
    await safeByDelegate.connect({})
  })

  it('Enqueues a simple contract deployment transaction by a delegate', async () => {
    const simpleContractDeploymentTx = getDeployTx(SimpleContract[AbiSymbol], SimpleContract[Bytecode], [])

    const safeDeploymentTx: SafeTransactionDataPartial = {
      to: safeByOwner.getAddress(),
      data: simpleContractDeploymentTx.data as string,
      value: '0',
      safeTxGas: 1000000
    }
    const safeTransaction = await safeByOwner.createTransaction(safeDeploymentTx)
    const safeTransactionHash = await safeByOwner.getTransactionHash(safeTransaction)
    await safeServiceClient.proposeTransaction({
      safeAddress: safeByOwner.getAddress(),
      safeTxHash: safeTransactionHash,
      safeTransaction,
      senderAddress: await owner.getAddress()
    })

    console.log(`Simple contract deployment via Safe tx hash: ${safeTransactionHash}`)
  })

  it('Find tx details', async () => {
    const t = await safeServiceClient.getTransaction('0x683fe944de35598048d190a7e39932c0d4b8036805c859eaa1d4f224e8b07dfa')
    const pending = await safeServiceClient.getPendingTransactions(safeByOwner.getAddress())

    const approvalResult = await safeByOwner.approveTransactionHash(t.safeTxHash)
    //safeByOwner.executeTransaction()
  })
})

Also:

export function getDeployTx(abi: Abi, bytecode: string, args: any[]) {
  return new ContractFactory(abi, bytecode).getDeployTransaction(...args)
}

It's automatically approved (because of the owner) and when I execute from Safe UI it succeeds but internal transactions fail.

  1. How can I know why?
  2. Could you provide an example of working contract deployment using just ethers+coresdk+client (instead of hardhad or trufle)?

TypeError after build

Description

I got the following error after building and calling the createSafe method.

EthersSafeFactory.ts:104 Uncaught (in promise) TypeError: Cannot read property 'args' of undefined
at EthersSafeFactory.deployProxy (EthersSafeFactory.ts:104)

Environment

  • Environment: node (svelte)

Steps to reproduce

  1. yarn build
  2. Implement node_module in a project
  3. Follow the instructions in the README to create a safe

Expected result

It should be able to create a safe as described in the tests

Additional context

I assume this has something to do with the build as the tests are passing while the method throws an error when I try to call the method in /dist after the build.
The error probably results from the following line: https://github.com/rsksmart/safe-core-sdk/blob/develop/src/EthersSafeFactory.ts#L104

Pass error messages from a transaction service to the safe-service-client

Background:
Got a ping from the Scaffold-eth team, they were frustrated at a blank error message received from the safe-service-client. Please see screenshot attatched:

When the team interacted directly with the transaction service, they found the error was that the addresses were not checksummed.

photo_2021-08-30 15 35 00

Send 0 for safeTxGas

Overview

safeTxGas is a workaround that was used so RPC providers could estimate correctly the gas used by a Safe transaction. This way we could get a valid gasLimit and avoid running out of gas because transaction was estimated lower than the real cost.
Since v1.3.0 this workaround is not necessary any more as now a transaction failing by low gas will revert instead of succeed, and we could simply send a 0 value and let the wallets to estimate the full cost in gas of the transaction.

From the contract code comments:

If no safeTxGas and no gasPrice was set (e.g. both are 0),
then the internal tx is required to be successful
This makes it possible to use `estimateGas` without issues,
as it searches for the minimum gas where the tx doesn't revert

Goals

  • Send safeTxGas=0 when sending a transaction from a Safe that is using at least v1.3.0 version of the smart contract
  • Export standardizeSafeTransactionData

Requirements

  • For v1.3.0 safes, send a safeTxGas=0
  • For earlier version (esp. v1.1.1), keep estimating and sending the value

Accept null for signerAddress

Web3Adapter takes signerAddress, typed as string. In safe-react we use the following function (so allowing string | null would be a great help):

export const getAccountFrom = async (web3Provider: Web3): Promise<string | null> => {
  const accounts = await web3Provider.eth.getAccounts()
  return accounts && accounts.length > 0 ? accounts[0] : null
}

Methods that then require the use of signerAddress should throw.

Increase nonce when proposing a new transaction

If the Safe Service Client is used to propose some transactions before any of them is executed, they will all have the same nonce. The current nonce should be retrieved and incremented before proposing each transaction.

L2 Initialization not working

Prerequisites

Deploy a gnosis smart contract on polygon!

Description

This is a sample using an ERC-20 Token. It seems that it cannot find the ABI for the safe from the depth of the SDK.

I'm not sure what to do here and how to configure it. If I require a ContractNetworksConfig, how would it look like?

    const ethAdapterOwner1 = new Web3Adapter({
      web3,
      signerAddress: '0x647C8f25Df7725747ab04BB71Ab606b8479A1435'
    })
    const safeSdk: Safe = await Safe.create(
      {
          ethAdapter: ethAdapterOwner1,
          safeAddress: '0xeC31635F253059EDf229ed69ab704f785e44637C',
      })

This throws the following error:

errors.js:107 Uncaught (in promise) Error: You must provide the json interface of the contract when instantiating a contract object.
    at Object.ContractMissingABIError (errors.js:107)
    at Contract (index.js:60)
    at new Contract (index.js:257)
    at Web3Adapter.getContract (eval at hmrApply (runtime-d6a2b2435d7a0f89.js:297), <anonymous>:61:16)
    at Web3Adapter.getSafeContract (eval at hmrApply (runtime-d6a2b2435d7a0f89.js:297), <anonymous>:43:35)
    at ContractManager.init (contractManager.ts:31)
    at async Function.create (contractManager.ts:20)
    at async Safe.init (Safe.ts:110)
    at async Function.create (Safe.ts:92)

Environment

  • Safe Core SDK version: latest
  • Safe contract version: 1.3.0
  • Environment:
    • chrome

Steps to reproduce

see aboe

Expected result

no error

Allow passing nonce to methods building the transactions

Context / issue

There's no way to pass a nonce of the transaction to methods that build a specific transaction (change threshold, owner management, etc.). This behavior requires workarounds for multi-tx interactions by encoding transaction call data and using the raw createTransaciton method.

Proposed solution

Allow passing custom nonce or the same set of options as createTransaction

Alternatives

  • encoding transaction call data and using the raw createTransaciton method

Additional context

5afe/safe-react#1729 (comment)

Error in documentation of safe-core-sdk

Description

The documentation of the safe-core-sdk has an error in the API Reference / connect section:
https://github.com/gnosis/safe-core-sdk/tree/main/packages/safe-core-sdk#api-reference

The code sample for the contractNetworks property was probably copy-pasted from the create section. I assume it should use connect instead of create.

Expected result

Documentation should read like:

const safeSdk = await Safe.connect({ ethAdapter, safeAddress, contractNetworks })

safe-core-sdk README outdated

The README of the safe-core-sdk package is outdated, and it doesn't include the changes related to the introduction of the TransactionResult interface.
All the examples with execute or approveTransactionHash call the wait method on the TransactionResult interface, but it doesn't include such method.

Example

Wrong version:

const approveTxResponse = await safeSdk2.approveTransactionHash(txHash)
await approveTxResponse.wait()

Fixed version:

const executeTxResponse = await safeSdk3.executeTransaction(safeTransaction)
await executeTxResponse.transactionResponse?.wait()

Add web3 support

Make the safe-core-sdk compatible not only with ethersjs but also with web3

Handle on-chain signatures

Add functions to submit signatures

  • Combining signatures
  • Send to contract
  • Confirming on-chain signatures

Export EthAdapterTransaction

Export EthAdapterTransaction so it can be imported like this:

import { EthAdapterTransaction } from '@gnosis.pm/safe-core-sdk'
...
const txConfig: EthAdapterTransaction = { ... }
await ethAdapter.estimateGas(txConfig)

Currrently it must be imported this way:

import { EthAdapterTransaction } from '@gnosis.pm/safe-core-sdk/dist/src/ethereumLibs/EthAdapter'

Export EthSignSignature class

Export EthSignSignature to avoid importing it from @gnosis.pm/safe-core-sdk/dist/src/utils/signatures/SafeSignature

Fix validation of new threshold when an owner is added with a new threshold

Description

Currently there is an incorrect validation of the threshold when a new owner is added with a new threshold.

const safeTx = await sdk.getAddOwnerTx(newOwnerAddress, newThreshold)

The method that validates the threshold is:

private validateThreshold(threshold: number, numOwners: number): void {
  if (threshold <= 0) {
    throw new Error('Threshold needs to be greater than 0')
  }
  if (threshold > numOwners) {
    throw new Error('Threshold cannot exceed owner count')
  }
}

Calling getAddOwnerTx(...) validates the threshold this way:

validateThreshold(newThreshold, owners.length) // owners does not contain the new owner here

It should be validated this other way (to take into account the new owner):

validateThreshold(newThreshold, owners.length + 1) // owners does not contain the new owner here

Steps to reproduce

  1. Set up a Safe with 1 owner
  2. Call getAddOwnerTx("0x...", 2). This will throw an exception with the error message: "'Threshold cannot exceed owner count"

Expected result

Adding a new owner and updating the threshold of an existing Safe where the new threshold is equal to the amount of new owners should work.

Improve management of delegates

  • Allow to revoke all the delegates of a Safe address by calling the new endpoint in the transaction-service.

  • Replace the signature with a signer in the methods to manage the delegates (the generation of the signature will be handled internally)

Unable to propose transaction.

Prerequisites

Deploy a contract on polygon

Description

I'm following the vanilla description from core sdk and client sdk and run into an error:

Uncaught TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
    at Object.sendRequest (httpRequests.ts:16)
    at SafeServiceClient.proposeTransaction (SafeServiceClient.ts:368)
    at tmp (sample.ts:68)
    at async <anonymous>:1:1
sendRequest @ httpRequests.ts:16
proposeTransaction @ SafeServiceClient.ts:368
tmp @ sample.ts:68
setTimeout (async)
runTimeout @ browser.js:41
process.nextTick @ browser.js:143
eval @ util.js:694
Promise.then (async)
bound bound request @ util.js:694
RequestManager.send @ index.js:155
sendRequest @ index.js:615
send @ index.js:647
_executeMethod @ index.js:768
getTransactionHash @ GnosisSafeContractWeb3.ts:62
getTransactionHash @ Safe.ts:319
tmp @ sample.ts:59
await in tmp (async)
(anonymous) @ VM5460:1`

I'm not sure if I'm doing it correctly and am basically try & error myself through the various SDKs, as I was not able to found documentation around this. My understanding is that this should be doable from a browser?

Environment

  • Safe Core SDK version: 1.1.1
  • Safe contract version: 1.3.0
  • Environment:
    • Chrome

Steps to reproduce

Run this code;

const safeAddress = '0xeC31635F253059EDf229ed69ab704f785e44637C';
    const signerAddress = '0x647C8f25Df7725747ab04BB71Ab606b8479A1435'
    // somehow load web3
    const web3 = detectWeb3()
    const abi = [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousTWAPEpochPeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTWAPEpochPeriod","type":"uint256"}],"name":"TWAPEpochChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTWAPOracle","type":"address"},{"indexed":true,"internalType":"address","name":"newTWAPOracle","type":"address"}],"name":"TWAPOracleChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newTWAPSource","type":"address"}],"name":"TWAPSourceAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"removedTWAPSource","type":"address"}],"name":"TWAPSourceRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"_burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTWAPSourceDexPool_","type":"address"}],"name":"addTWAPSource","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTWAPEpochPeriod_","type":"uint256"}],"name":"changeTWAPEpochPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTWAPOracle_","type":"address"}],"name":"changeTWAPOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"twapSourceToRemove_","type":"address"}],"name":"removeTWAPSource","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault_","type":"address"}],"name":"setVault","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner_","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"twapEpochPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twapOracle","outputs":[{"internalType":"contract ITWAPOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
    const address = '0x4e78011Ce80ee02d2c3e649Fb657E45898257815'
    const contract = new web3.eth.Contract(abi, address)
    const data = contract.methods.approve('0x4e78011Ce80ee02d2c3e649Fb657E45898257815', 12).encodeABI()

    const ethAdapterOwner1 = new Web3Adapter({
      web3: web3,
      signerAddress
    })
    const safeSdk: Safe = await Safe.create(
      {
          ethAdapter: ethAdapterOwner1,
          safeAddress: '0xeC31635F253059EDf229ed69ab704f785e44637C',
      })

    const transaction: SafeTransactionDataPartial = {
      to: address,
      value: '0',
      data: data
    }
    const safeTransaction = await safeSdk.createTransaction(transaction)
    const safeTxHash = await safeSdk.getTransactionHash(safeTransaction)
  
    const transactionConfig: ProposeTransactionProps = {
      safeAddress,
      safeTransaction,
      safeTxHash,
      senderAddress: signerAddress
    }
    const safeService = new SafeServiceClient('https://safe-transaction.gnosis.io')
    await safeService.proposeTransaction(transactionConfig)

Expected result

No errors :-)

Fix SafeTransactionDataPartial import

This PR (#87) fixed a wrong import of the SafeTranscationDataPartial type in the README
There is also an import that can be improved in packages/safe-core-sdk/src/utils/transactions/types.ts

Set custom/optional parameters in MultiSend transaction

Description

When creating a multisend transaction the user is not allowed to set the optional params included in SafeTransactionDataPartial (safeTxGas, baseGas, gasPrice, gasToken, refundReceiver and nonce).

Environment

  • Safe Core SDK last version

Expected result

The user is allowed to set the optional params included in SafeTransactionDataPartial (safeTxGas, baseGas, gasPrice, gasToken, refundReceiver and nonce) when creating a multisend transaction.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.