@rabby-wallet/gnosis-sdk 1.3.5 → 1.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { Axios, AxiosAdapter } from 'axios';
1
+ import { SafeTransactionDataPartial } from "@gnosis.pm/safe-core-sdk-types";
2
+ import { Axios, AxiosAdapter } from "axios";
2
3
  export interface SafeInfo {
3
4
  address: string;
4
5
  fallbackHandler: string;
@@ -50,5 +51,6 @@ export default class RequestProvider {
50
51
  postTransactions(safeAddres: string, data: any): Promise<void>;
51
52
  getSafeInfo(safeAddress: string): Promise<SafeInfo>;
52
53
  confirmTransaction(hash: string, data: any): Promise<void>;
54
+ getSafeTxGas(safeAddress: string, safeVersion: string, safeTxData: SafeTransactionDataPartial): Promise<number | undefined>;
53
55
  }
54
56
  export {};
package/dist/api.js CHANGED
@@ -1,25 +1,73 @@
1
- import axios from 'axios';
2
- import { toChecksumAddress } from 'web3-utils';
1
+ import { isLegacyVersion } from "./utils";
2
+ import axios from "axios";
3
+ import { toChecksumAddress } from "web3-utils";
3
4
  const HOST_MAP = {
4
- '1': 'https://safe-transaction-mainnet.safe.global/api/v1',
5
- '137': 'https://safe-transaction-polygon.safe.global/api/v1',
6
- '56': 'https://safe-transaction-bsc.safe.global/api/v1',
7
- '100': 'https://safe-transaction-gnosis-chain.safe.global/api/v1',
8
- '43114': 'https://safe-transaction-avalanche.safe.global/api/v1',
9
- '42161': 'https://safe-transaction-arbitrum.safe.global/api/v1',
10
- '10': 'https://safe-transaction-optimism.safe.global/api/v1',
11
- '1313161554': 'https://safe-transaction-aurora.safe.global/api/v1',
5
+ /**
6
+ * eth
7
+ */
8
+ "1": "https://safe-transaction-mainnet.safe.global/api/v1",
9
+ /**
10
+ * polygon
11
+ */
12
+ "137": "https://safe-transaction-polygon.safe.global/api/v1",
13
+ /**
14
+ * bsc
15
+ */
16
+ "56": "https://safe-transaction-bsc.safe.global/api/v1",
17
+ /**
18
+ * Gnosis Chain
19
+ */
20
+ "100": "https://safe-transaction-gnosis-chain.safe.global/api/v1",
21
+ /**
22
+ * avalanche
23
+ */
24
+ "43114": "https://safe-transaction-avalanche.safe.global/api/v1",
25
+ /**
26
+ * arbitrum
27
+ */
28
+ "42161": "https://safe-transaction-arbitrum.safe.global/api/v1",
29
+ /**
30
+ * Optimism
31
+ */
32
+ "10": "https://safe-transaction-optimism.safe.global/api/v1",
33
+ /**
34
+ * Aurora
35
+ */
36
+ "1313161554": "https://safe-transaction-aurora.safe.global/api/v1",
37
+ /**
38
+ * Base
39
+ */
12
40
  "8453": "https://safe-transaction-base.safe.global/api/v1",
41
+ /**
42
+ * Celo
43
+ */
44
+ "42220": "https://safe-transaction-celo.safe.global/api/v1",
45
+ /**
46
+ * Polygon zkEVM
47
+ */
48
+ "1101": "https://safe-transaction-zkevm.safe.global/api/v1",
49
+ /**
50
+ * zksync era
51
+ */
52
+ "324": "https://safe-transaction-zksync.safe.global/api/v1",
53
+ /**
54
+ * scroll
55
+ */
56
+ "534352": "https://safe-transaction-scroll.safe.global/api/v1",
57
+ /**
58
+ * linea
59
+ */
60
+ "59144": "https://safe-transaction-linea.safe.global/api/v1",
13
61
  };
14
62
  export default class RequestProvider {
15
63
  constructor(networkId, adapter) {
16
64
  if (!(networkId in HOST_MAP)) {
17
- throw new Error('Wrong networkId');
65
+ throw new Error("Wrong networkId");
18
66
  }
19
67
  this.host = HOST_MAP[networkId];
20
68
  this.request = axios.create({
21
69
  baseURL: this.host,
22
- adapter
70
+ adapter,
23
71
  });
24
72
  this.request.interceptors.response.use((response) => {
25
73
  return response.data;
@@ -29,8 +77,8 @@ export default class RequestProvider {
29
77
  return this.request.get(`/safes/${toChecksumAddress(safeAddress)}/multisig-transactions/`, {
30
78
  params: {
31
79
  executed: false,
32
- nonce__gte: nonce
33
- }
80
+ nonce__gte: nonce,
81
+ },
34
82
  });
35
83
  }
36
84
  postTransactions(safeAddres, data) {
@@ -42,4 +90,24 @@ export default class RequestProvider {
42
90
  confirmTransaction(hash, data) {
43
91
  return this.request.post(`/multisig-transactions/${hash}/confirmations/`, data);
44
92
  }
93
+ // https://github.com/safe-global/safe-wallet-web/blob/dev/src/services/tx/tx-sender/recommendedNonce.ts#L24
94
+ async getSafeTxGas(safeAddress, safeVersion, safeTxData) {
95
+ const isSafeTxGasRequired = isLegacyVersion(safeVersion);
96
+ // For 1.3.0+ Safes safeTxGas is not required
97
+ if (!isSafeTxGasRequired)
98
+ return 0;
99
+ const address = toChecksumAddress(safeAddress);
100
+ try {
101
+ const estimation = await this.request.post(`/safes/${address}/multisig-transactions/estimations/`, {
102
+ to: toChecksumAddress(safeTxData.to),
103
+ value: +safeTxData.value || 0,
104
+ data: safeTxData.data,
105
+ operation: safeTxData.operation,
106
+ });
107
+ return Number(estimation.safeTxGas);
108
+ }
109
+ catch (e) {
110
+ console.error(e);
111
+ }
112
+ }
45
113
  }
package/dist/index.js CHANGED
@@ -102,7 +102,7 @@ class Safe {
102
102
  return nonce.toNumber();
103
103
  }
104
104
  async buildTransaction(data) {
105
- const transaction = await standardizeSafeTransactionData(this.safeAddress, this.contract, this.provider, data);
105
+ const transaction = await standardizeSafeTransactionData(this.safeAddress, this.contract, this.provider, data, this.network, this.version);
106
106
  return new SafeTransaction(transaction);
107
107
  }
108
108
  async getTransactionHash(transaction) {
package/dist/utils.d.ts CHANGED
@@ -3,8 +3,9 @@ import { OperationType, SafeTransactionData, SafeTransactionDataPartial, SafeSig
3
3
  import EthSignSignature from "@gnosis.pm/safe-core-sdk/dist/src/utils/signatures/SafeSignature";
4
4
  export declare function sameString(str1: string, str2: string): boolean;
5
5
  export declare function isRestrictedAddress(address: string): boolean;
6
+ export declare const isLegacyVersion: (safeVersion: string) => boolean;
6
7
  export declare function estimateTxGas(safeAddress: string, safeContract: Contract, provider: providers.Web3Provider, to: string, valueInWei: string, data: string, operation: OperationType): Promise<number>;
7
- export declare function standardizeSafeTransactionData(safeAddress: string, safeContract: Contract, provider: any, tx: SafeTransactionDataPartial): Promise<SafeTransactionData>;
8
+ export declare function standardizeSafeTransactionData(safeAddress: string, safeContract: Contract, provider: any, tx: SafeTransactionDataPartial, network: string, version: string): Promise<SafeTransactionData>;
8
9
  export declare function generatePreValidatedSignature(ownerAddress: string): SafeSignature;
9
10
  export declare function isTxHashSignedWithPrefix(txHash: string, signature: string, ownerAddress: string): boolean;
10
11
  export declare function adjustVInSignature(signature: string, hasPrefix: boolean): string;
package/dist/utils.js CHANGED
@@ -3,6 +3,9 @@ import { OperationType, } from "@gnosis.pm/safe-core-sdk-types";
3
3
  import { bufferToHex, ecrecover, pubToAddress } from "ethereumjs-util";
4
4
  import { ZERO_ADDRESS, SENTINEL_ADDRESS } from "./constants";
5
5
  import EthSignSignature from "@gnosis.pm/safe-core-sdk/dist/src/utils/signatures/SafeSignature";
6
+ import semverSatisfies from "semver/functions/satisfies";
7
+ import RequestProvider from "./api";
8
+ import Safe from "./index";
6
9
  function estimateDataGasCosts(data) {
7
10
  const reducer = (accumulator, currentValue) => {
8
11
  if (currentValue === "0x") {
@@ -27,6 +30,10 @@ function isSentinelAddress(address) {
27
30
  export function isRestrictedAddress(address) {
28
31
  return isZeroAddress(address) || isSentinelAddress(address);
29
32
  }
33
+ export const isLegacyVersion = (safeVersion) => {
34
+ const LEGACY_VERSION = "<1.3.0";
35
+ return semverSatisfies(safeVersion, LEGACY_VERSION);
36
+ };
30
37
  export async function estimateTxGas(safeAddress, safeContract, provider, to, valueInWei, data, operation) {
31
38
  let txGasEstimation = 0;
32
39
  const estimateData = safeContract.interface.encodeFunctionData("requiredTxGas", [to, valueInWei, data, operation]);
@@ -78,7 +85,7 @@ export async function estimateTxGas(safeAddress, safeContract, provider, to, val
78
85
  return Promise.reject(error);
79
86
  }
80
87
  }
81
- export async function standardizeSafeTransactionData(safeAddress, safeContract, provider, tx) {
88
+ export async function standardizeSafeTransactionData(safeAddress, safeContract, provider, tx, network, version) {
82
89
  var _a, _b, _c, _d, _e;
83
90
  const standardizedTxs = {
84
91
  to: tx.to,
@@ -91,10 +98,11 @@ export async function standardizeSafeTransactionData(safeAddress, safeContract,
91
98
  refundReceiver: tx.refundReceiver || ZERO_ADDRESS,
92
99
  nonce: (_d = tx.nonce) !== null && _d !== void 0 ? _d : (await safeContract.nonce()).toNumber(),
93
100
  };
94
- const safeTxGas = (_e = tx.safeTxGas) !== null && _e !== void 0 ? _e : (await estimateTxGas(safeAddress, safeContract, provider, standardizedTxs.to, standardizedTxs.value, standardizedTxs.data, standardizedTxs.operation));
101
+ const request = new RequestProvider(network, Safe.adapter);
102
+ const safeTxGas = (_e = tx.safeTxGas) !== null && _e !== void 0 ? _e : (await request.getSafeTxGas(safeAddress, version, standardizedTxs));
95
103
  return {
96
104
  ...standardizedTxs,
97
- safeTxGas,
105
+ safeTxGas: safeTxGas || 0,
98
106
  };
99
107
  }
100
108
  export function generatePreValidatedSignature(ownerAddress) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rabby-wallet/gnosis-sdk",
3
- "version": "1.3.5",
3
+ "version": "1.3.7",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -16,11 +16,12 @@
16
16
  "@ethersproject/solidity": "^5.5.0",
17
17
  "@gnosis.pm/safe-core-sdk": "^1.0.0",
18
18
  "@gnosis.pm/safe-core-sdk-types": "^0.1.1",
19
- "@safe-global/safe-deployments": "^1.25.0",
19
+ "@safe-global/safe-deployments": "^1.37.2",
20
20
  "axios": "^0.24.0",
21
21
  "bignumber.js": "^9.0.2",
22
22
  "ethereumjs-util": "^7.1.3",
23
23
  "ethers": "^5.5.1",
24
+ "semver": "^7.5.4",
24
25
  "typescript": "^4.5.0",
25
26
  "web3-core": "^1.6.0"
26
27
  },
package/src/api.ts CHANGED
@@ -1,5 +1,7 @@
1
- import axios, { Axios, AxiosAdapter } from 'axios';
2
- import { toChecksumAddress } from 'web3-utils';
1
+ import { SafeTransactionDataPartial } from "@gnosis.pm/safe-core-sdk-types";
2
+ import { isLegacyVersion } from "./utils";
3
+ import axios, { Axios, AxiosAdapter } from "axios";
4
+ import { toChecksumAddress } from "web3-utils";
3
5
 
4
6
  export interface SafeInfo {
5
7
  address: string;
@@ -46,15 +48,62 @@ export interface SafeTransactionItem {
46
48
  }
47
49
 
48
50
  const HOST_MAP = {
49
- '1': 'https://safe-transaction-mainnet.safe.global/api/v1',
50
- '137': 'https://safe-transaction-polygon.safe.global/api/v1',
51
- '56': 'https://safe-transaction-bsc.safe.global/api/v1',
52
- '100': 'https://safe-transaction-gnosis-chain.safe.global/api/v1',
53
- '43114': 'https://safe-transaction-avalanche.safe.global/api/v1',
54
- '42161': 'https://safe-transaction-arbitrum.safe.global/api/v1',
55
- '10': 'https://safe-transaction-optimism.safe.global/api/v1',
56
- '1313161554': 'https://safe-transaction-aurora.safe.global/api/v1',
51
+ /**
52
+ * eth
53
+ */
54
+ "1": "https://safe-transaction-mainnet.safe.global/api/v1",
55
+ /**
56
+ * polygon
57
+ */
58
+ "137": "https://safe-transaction-polygon.safe.global/api/v1",
59
+ /**
60
+ * bsc
61
+ */
62
+ "56": "https://safe-transaction-bsc.safe.global/api/v1",
63
+ /**
64
+ * Gnosis Chain
65
+ */
66
+ "100": "https://safe-transaction-gnosis-chain.safe.global/api/v1",
67
+ /**
68
+ * avalanche
69
+ */
70
+ "43114": "https://safe-transaction-avalanche.safe.global/api/v1",
71
+ /**
72
+ * arbitrum
73
+ */
74
+ "42161": "https://safe-transaction-arbitrum.safe.global/api/v1",
75
+ /**
76
+ * Optimism
77
+ */
78
+ "10": "https://safe-transaction-optimism.safe.global/api/v1",
79
+ /**
80
+ * Aurora
81
+ */
82
+ "1313161554": "https://safe-transaction-aurora.safe.global/api/v1",
83
+ /**
84
+ * Base
85
+ */
57
86
  "8453": "https://safe-transaction-base.safe.global/api/v1",
87
+ /**
88
+ * Celo
89
+ */
90
+ "42220": "https://safe-transaction-celo.safe.global/api/v1",
91
+ /**
92
+ * Polygon zkEVM
93
+ */
94
+ "1101": "https://safe-transaction-zkevm.safe.global/api/v1",
95
+ /**
96
+ * zksync era
97
+ */
98
+ "324": "https://safe-transaction-zksync.safe.global/api/v1",
99
+ /**
100
+ * scroll
101
+ */
102
+ "534352": "https://safe-transaction-scroll.safe.global/api/v1",
103
+ /**
104
+ * linea
105
+ */
106
+ "59144": "https://safe-transaction-linea.safe.global/api/v1",
58
107
  };
59
108
 
60
109
  export default class RequestProvider {
@@ -63,14 +112,14 @@ export default class RequestProvider {
63
112
 
64
113
  constructor(networkId: string, adapter?: AxiosAdapter) {
65
114
  if (!(networkId in HOST_MAP)) {
66
- throw new Error('Wrong networkId');
115
+ throw new Error("Wrong networkId");
67
116
  }
68
117
 
69
118
  this.host = HOST_MAP[networkId];
70
119
 
71
120
  this.request = axios.create({
72
121
  baseURL: this.host,
73
- adapter
122
+ adapter,
74
123
  });
75
124
 
76
125
  this.request.interceptors.response.use((response) => {
@@ -87,8 +136,8 @@ export default class RequestProvider {
87
136
  {
88
137
  params: {
89
138
  executed: false,
90
- nonce__gte: nonce
91
- }
139
+ nonce__gte: nonce,
140
+ },
92
141
  }
93
142
  );
94
143
  }
@@ -110,4 +159,33 @@ export default class RequestProvider {
110
159
  data
111
160
  );
112
161
  }
162
+
163
+ // https://github.com/safe-global/safe-wallet-web/blob/dev/src/services/tx/tx-sender/recommendedNonce.ts#L24
164
+ async getSafeTxGas(
165
+ safeAddress: string,
166
+ safeVersion: string,
167
+ safeTxData: SafeTransactionDataPartial
168
+ ): Promise<number | undefined> {
169
+ const isSafeTxGasRequired = isLegacyVersion(safeVersion);
170
+
171
+ // For 1.3.0+ Safes safeTxGas is not required
172
+ if (!isSafeTxGasRequired) return 0;
173
+
174
+ const address = toChecksumAddress(safeAddress);
175
+
176
+ try {
177
+ const estimation: { safeTxGas: string } = await this.request.post(
178
+ `/safes/${address}/multisig-transactions/estimations/`,
179
+ {
180
+ to: toChecksumAddress(safeTxData.to),
181
+ value: +safeTxData.value || 0,
182
+ data: safeTxData.data,
183
+ operation: safeTxData.operation,
184
+ }
185
+ );
186
+ return Number(estimation.safeTxGas);
187
+ } catch (e) {
188
+ console.error(e);
189
+ }
190
+ }
113
191
  }
package/src/index.ts CHANGED
@@ -174,7 +174,9 @@ class Safe {
174
174
  this.safeAddress,
175
175
  this.contract,
176
176
  this.provider,
177
- data
177
+ data,
178
+ this.network,
179
+ this.version
178
180
  );
179
181
  return new SafeTransaction(transaction);
180
182
  }
package/src/utils.ts CHANGED
@@ -10,6 +10,9 @@ import {
10
10
  import { bufferToHex, ecrecover, pubToAddress } from "ethereumjs-util";
11
11
  import { ZERO_ADDRESS, SENTINEL_ADDRESS } from "./constants";
12
12
  import EthSignSignature from "@gnosis.pm/safe-core-sdk/dist/src/utils/signatures/SafeSignature";
13
+ import semverSatisfies from "semver/functions/satisfies";
14
+ import RequestProvider from "./api";
15
+ import Safe from "./index";
13
16
 
14
17
  function estimateDataGasCosts(data: string): number {
15
18
  const reducer = (accumulator: number, currentValue: string) => {
@@ -40,6 +43,11 @@ export function isRestrictedAddress(address: string): boolean {
40
43
  return isZeroAddress(address) || isSentinelAddress(address);
41
44
  }
42
45
 
46
+ export const isLegacyVersion = (safeVersion: string): boolean => {
47
+ const LEGACY_VERSION = "<1.3.0";
48
+ return semverSatisfies(safeVersion, LEGACY_VERSION);
49
+ };
50
+
43
51
  export async function estimateTxGas(
44
52
  safeAddress: string,
45
53
  safeContract: Contract,
@@ -109,7 +117,9 @@ export async function standardizeSafeTransactionData(
109
117
  safeAddress: string,
110
118
  safeContract: Contract,
111
119
  provider: any,
112
- tx: SafeTransactionDataPartial
120
+ tx: SafeTransactionDataPartial,
121
+ network: string,
122
+ version: string
113
123
  ): Promise<SafeTransactionData> {
114
124
  const standardizedTxs = {
115
125
  to: tx.to,
@@ -122,20 +132,13 @@ export async function standardizeSafeTransactionData(
122
132
  refundReceiver: tx.refundReceiver || ZERO_ADDRESS,
123
133
  nonce: tx.nonce ?? (await safeContract.nonce()).toNumber(),
124
134
  };
135
+ const request = new RequestProvider(network, Safe.adapter);
125
136
  const safeTxGas =
126
137
  tx.safeTxGas ??
127
- (await estimateTxGas(
128
- safeAddress,
129
- safeContract,
130
- provider,
131
- standardizedTxs.to,
132
- standardizedTxs.value,
133
- standardizedTxs.data,
134
- standardizedTxs.operation
135
- ));
138
+ (await request.getSafeTxGas(safeAddress, version, standardizedTxs));
136
139
  return {
137
140
  ...standardizedTxs,
138
- safeTxGas,
141
+ safeTxGas: safeTxGas || 0,
139
142
  };
140
143
  }
141
144