Skip to content

Commit

Permalink
Merge pull request #92 from gnosis/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
germartinez authored Oct 28, 2021
2 parents faf6459 + ee956bc commit efd4c79
Show file tree
Hide file tree
Showing 55 changed files with 1,648 additions and 496 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
branches:
- development
- main
env:
INFURA_KEY: ${{ secrets.INFURA_KEY }}
jobs:
test:
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
name: Hardhat Test
on: [push, pull_request]
env:
INFURA_KEY: ${{ secrets.INFURA_KEY }}
jobs:
test:
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@ deployments

# Typechain
typechain

openapi/
149 changes: 118 additions & 31 deletions packages/safe-core-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const safeSdk: Safe = await Safe.create({ ethAdapter: ethAdapterOwner1, safeAddr
### 3. Create a Safe transaction

```js
import { SafeTransactionDataPartial } from '@gnosis.pm/safe-core-sdk'
import { SafeTransactionDataPartial } from '@gnosis.pm/safe-core-sdk-types'

const transactions: SafeTransactionDataPartial[] = [{
to: '0x<address>',
Expand Down Expand Up @@ -260,35 +260,74 @@ const isOwner = await safeSdk.isOwner(address)
### createTransaction
Returns a Safe transaction ready to be signed by the owners and executed. Batched transactions are allowed if more than one transaction is added to the array of transactions.
Returns a Safe transaction ready to be signed by the owners and executed.
Each of the transactions provided as input to this function must be an object with the following properties:
```js
const transaction: SafeTransactionDataPartial = {
to,
data,
value,
operation, // Optional
safeTxGas, // Optional
baseGas, // Optional
gasPrice, // Optional
gasToken, // Optional
refundReceiver, // Optional
nonce // Optional
}
const safeTransaction = await safeSdk.createTransaction(transaction)
```
* `to`: Required.
* `data`: Required.
* `value`: Required.
* `operation`: Optional. `OperationType.Call` (0) is the default value.
* `safeTxGas`: Optional. The right gas estimation is the default value.
* `baseGas`: Optional. 0 is the default value.
* `gasPrice`: Optional. 0 is the default value.
* `gasToken`: Optional. 0x address is the default value.
* `refundReceiver`: Optional. 0x address is the default value.
* `nonce`: Optional. The current Safe nonce is the default value.
Batched transactions are allowed if more than one transaction are passed as an array of transactions.
Read more about the [Safe transaction properties](https://docs.gnosis.io/safe/docs/contracts_tx_execution/).
```js
const transactions: MetaTransactionData[] = [
{
to,
data,
value,
operation // Optional
},
// ...
]
const safeTransaction = await safeSdk.createTransaction(transactions)
```
This method can also receive the `options` parameter to set the optional properties in the MultiSend transaction:
```js
const transactions: SafeTransactionDataPartial[] = [
const transactions: MetaTransactionData[] = [
{
to: '0x<address>',
data: '0x<data>',
value: '<eth_value_in_wei>'
to,
data,
value,
operation
},
// ...
]
const safeTransaction = await safeSdk.createTransaction(...transactions)
const options: SafeTransactionOptionalProps = {
safeTxGas, // Optional
baseGas, // Optional
gasPrice, // Optional
gasToken, // Optional
refundReceiver, // Optional
nonce // Optional
}
const safeTransaction = await safeSdk.createTransaction(transactions, options)
```
If the optional properties are not manually set, the Safe transaction returned will have the default value for each one:
* `operation`: `OperationType.Call` (0) is the default value.
* `safeTxGas`: The right gas estimation is the default value.
* `baseGas`: 0 is the default value.
* `gasPrice`: 0 is the default value.
* `gasToken`: 0x address is the default value.
* `refundReceiver`: 0x address is the default value.
* `nonce`: The current Safe nonce is the default value.
Read more about the [Safe transaction properties](https://docs.gnosis.io/safe/docs/contracts_tx_execution/).
### createRejectionTransaction
Returns a Safe transaction ready to be signed by the owners that invalidates the pending Safe transaction/s with a specific nonce.
Expand Down Expand Up @@ -375,6 +414,20 @@ const txResponse = await safeSdk.executeTransaction(safeTransaction)
await txResponse.transactionResponse?.wait()
```
This method can optionally receive the `options` parameter:
```js
const options: SafeTransactionOptionalProps = {
safeTxGas, // Optional
baseGas, // Optional
gasPrice, // Optional
gasToken, // Optional
refundReceiver, // Optional
nonce // Optional
}
const safeTransaction = await safeSdk.getEnableModuleTx(moduleAddress, options)
```
### getDisableModuleTx
Returns a Safe transaction ready to be signed that will disable a Safe module.
Expand All @@ -385,48 +438,76 @@ const txResponse = await safeSdk.executeTransaction(safeTransaction)
await txResponse.transactionResponse?.wait()
```
This method can optionally receive the `options` parameter:
```js
const options: SafeTransactionOptionalProps = { ... }
const safeTransaction = await safeSdk.getDisableModuleTx(moduleAddress, options)
```
### getAddOwnerTx
Returns the Safe transaction to add an owner and update the threshold.
Returns the Safe transaction to add an owner and optionally change the threshold.
```js
const safeTransaction = await safeSdk.getAddOwnerTx(newOwnerAddress, newThreshold)
const params: AddOwnerTxParams = {
ownerAddress,
threshold // Optional. If `threshold` is not provided the current threshold will not change.
}
const safeTransaction = await safeSdk.getAddOwnerTx(params)
const txResponse = await safeSdk.executeTransaction(safeTransaction)
await txResponse.transactionResponse?.wait()
```
If `threshold` is not provided, the current threshold will not change.
This method can optionally receive the `options` parameter:
```js
const safeTransaction = await safeSdk.getAddOwnerTx(newOwnerAddress)
const options: SafeTransactionOptionalProps = { ... }
const safeTransaction = await safeSdk.getAddOwnerTx(params, options)
```
### getRemoveOwnerTx
Returns the Safe transaction to remove an owner and update the threshold.
Returns the Safe transaction to remove an owner and optionally change the threshold.
```js
const safeTransaction = await safeSdk.getRemoveOwnerTx(ownerAddress, newThreshold)
const params: RemoveOwnerTxParams = {
ownerAddress,
newThreshold // Optional. If `newThreshold` is not provided, the current threshold will be decreased by one.
}
const safeTransaction = await safeSdk.getRemoveOwnerTx(params)
const txResponse = await safeSdk.executeTransaction(safeTransaction)
await txResponse.transactionResponse?.wait()
```
If `threshold` is not provided, the current threshold will be decreased by one.
This method can optionally receive the `options` parameter:
```js
const safeTransaction = await safeSdk.getRemoveOwnerTx(ownerAddress)
const options: SafeTransactionOptionalProps = { ... }
const safeTransaction = await safeSdk.getRemoveOwnerTx(params, options)
```
### getSwapOwnerTx
Returns the Safe transaction to replace an owner of the Safe with a new one.
```js
const safeTransaction = await safeSdk.getSwapOwnerTx(oldOwnerAddress, newOwnerAddress)
const params: SwapOwnerTxParams = {
oldOwnerAddress,
newOwnerAddress
}
const safeTransaction = await safeSdk.getSwapOwnerTx(params)
const txResponse = await safeSdk.executeTransaction(safeTransaction)
await txResponse.transactionResponse?.wait()
```
This method can optionally receive the `options` parameter:
```js
const options: SafeTransactionOptionalProps = { ... }
const safeTransaction = await safeSdk.getSwapOwnerTx(params, options)
```
### getChangeThresholdTx
Returns the Safe transaction to change the threshold.
Expand All @@ -437,6 +518,13 @@ const txResponse = await safeSdk.executeTransaction(safeTransaction)
await txResponse.transactionResponse?.wait()
```
This method can optionally receive the `options` parameter:
```js
const options: SafeTransactionOptionalProps = { ... }
const safeTransaction = await safeSdk.getChangeThresholdTx(newThreshold, options)
```
### executeTransaction
Executes a Safe transaction.
Expand All @@ -454,11 +542,10 @@ Optionally, `gasLimit` and `gasPrice` values can be passed as execution options,
```js
const options: TransactionOptions = {
gasLimit: 123456,
gasPrice: 123 // Optional parameter.
gasLimit,
gasPrice // Optional
}
const txResponse = await safeSdk.executeTransaction(safeTransaction, options)
await txResponse.transactionResponse?.wait()
```
## License
Expand Down
2 changes: 1 addition & 1 deletion packages/safe-core-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gnosis.pm/safe-core-sdk",
"version": "0.4.0",
"version": "1.0.0",
"description": "Safe Core SDK",
"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts",
Expand Down
46 changes: 28 additions & 18 deletions packages/safe-core-sdk/src/Safe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BigNumber } from '@ethersproject/bignumber'
import {
MetaTransactionData,
OperationType,
SafeSignature,
SafeTransaction,
Expand All @@ -15,7 +16,7 @@ import { generatePreValidatedSignature, generateSignature } from './utils/signat
import { estimateGasForTransactionExecution } from './utils/transactions/gas'
import EthSafeTransaction from './utils/transactions/SafeTransaction'
import {
CallTransactionOptionalProps,
SafeTransactionOptionalProps,
TransactionOptions,
TransactionResult
} from './utils/transactions/types'
Expand Down Expand Up @@ -234,28 +235,37 @@ class Safe {
* @param safeTransactions - The list of transactions to process
* @returns The Safe transaction
*/
async createTransaction(safeTransactions: SafeTransactionDataPartial): Promise<SafeTransaction>
async createTransaction(
...safeTransactions: SafeTransactionDataPartial[]
safeTransactions: MetaTransactionData[],
options?: SafeTransactionOptionalProps
): Promise<SafeTransaction>
async createTransaction(
safeTransactions: SafeTransactionDataPartial | MetaTransactionData[],
options?: SafeTransactionDataPartial
): Promise<SafeTransaction> {
if (safeTransactions.length === 1) {
if (safeTransactions instanceof Array) {
const multiSendData = encodeMultiSendData(
safeTransactions.map(standardizeMetaTransactionData)
)
const multiSendTransaction = {
...options,
to: this.#contractManager.multiSendContract.getAddress(),
value: '0',
data: this.#contractManager.multiSendContract.encode('multiSend', [multiSendData]),
operation: OperationType.DelegateCall
}
const standardizedTransaction = await standardizeSafeTransactionData(
this.#contractManager.safeContract,
this.#ethAdapter,
safeTransactions[0]
multiSendTransaction
)
return new EthSafeTransaction(standardizedTransaction)
}
const multiSendData = encodeMultiSendData(safeTransactions.map(standardizeMetaTransactionData))
const multiSendTransaction = {
to: this.#contractManager.multiSendContract.getAddress(),
value: '0',
data: this.#contractManager.multiSendContract.encode('multiSend', [multiSendData]),
operation: OperationType.DelegateCall
}
const standardizedTransaction = await standardizeSafeTransactionData(
this.#contractManager.safeContract,
this.#ethAdapter,
multiSendTransaction
safeTransactions
)
return new EthSafeTransaction(standardizedTransaction)
}
Expand Down Expand Up @@ -368,7 +378,7 @@ class Safe {
*/
async getEnableModuleTx(
moduleAddress: string,
options?: CallTransactionOptionalProps
options?: SafeTransactionOptionalProps
): Promise<SafeTransaction> {
const safeTransaction = await this.createTransaction({
to: this.getAddress(),
Expand All @@ -390,7 +400,7 @@ class Safe {
*/
async getDisableModuleTx(
moduleAddress: string,
options?: CallTransactionOptionalProps
options?: SafeTransactionOptionalProps
): Promise<SafeTransaction> {
const safeTransaction = await this.createTransaction({
to: this.getAddress(),
Expand All @@ -414,7 +424,7 @@ class Safe {
*/
async getAddOwnerTx(
{ ownerAddress, threshold }: AddOwnerTxParams,
options?: CallTransactionOptionalProps
options?: SafeTransactionOptionalProps
): Promise<SafeTransaction> {
const safeTransaction = await this.createTransaction({
to: this.getAddress(),
Expand All @@ -438,7 +448,7 @@ class Safe {
*/
async getRemoveOwnerTx(
{ ownerAddress, threshold }: RemoveOwnerTxParams,
options?: CallTransactionOptionalProps
options?: SafeTransactionOptionalProps
): Promise<SafeTransaction> {
const safeTransaction = await this.createTransaction({
to: this.getAddress(),
Expand All @@ -462,7 +472,7 @@ class Safe {
*/
async getSwapOwnerTx(
{ oldOwnerAddress, newOwnerAddress }: SwapOwnerTxParams,
options?: CallTransactionOptionalProps
options?: SafeTransactionOptionalProps
): Promise<SafeTransaction> {
const safeTransaction = await this.createTransaction({
to: this.getAddress(),
Expand All @@ -484,7 +494,7 @@ class Safe {
*/
async getChangeThresholdTx(
threshold: number,
options?: CallTransactionOptionalProps
options?: SafeTransactionOptionalProps
): Promise<SafeTransaction> {
const safeTransaction = await this.createTransaction({
to: this.getAddress(),
Expand Down
Loading

0 comments on commit efd4c79

Please sign in to comment.