@rabby-wallet/gnosis-sdk 1.3.5 → 1.3.6

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,65 @@
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",
13
53
  };
14
54
  export default class RequestProvider {
15
55
  constructor(networkId, adapter) {
16
56
  if (!(networkId in HOST_MAP)) {
17
- throw new Error('Wrong networkId');
57
+ throw new Error("Wrong networkId");
18
58
  }
19
59
  this.host = HOST_MAP[networkId];
20
60
  this.request = axios.create({
21
61
  baseURL: this.host,
22
- adapter
62
+ adapter,
23
63
  });
24
64
  this.request.interceptors.response.use((response) => {
25
65
  return response.data;
@@ -29,8 +69,8 @@ export default class RequestProvider {
29
69
  return this.request.get(`/safes/${toChecksumAddress(safeAddress)}/multisig-transactions/`, {
30
70
  params: {
31
71
  executed: false,
32
- nonce__gte: nonce
33
- }
72
+ nonce__gte: nonce,
73
+ },
34
74
  });
35
75
  }
36
76
  postTransactions(safeAddres, data) {
@@ -42,4 +82,24 @@ export default class RequestProvider {
42
82
  confirmTransaction(hash, data) {
43
83
  return this.request.post(`/multisig-transactions/${hash}/confirmations/`, data);
44
84
  }
85
+ // https://github.com/safe-global/safe-wallet-web/blob/dev/src/services/tx/tx-sender/recommendedNonce.ts#L24
86
+ async getSafeTxGas(safeAddress, safeVersion, safeTxData) {
87
+ const isSafeTxGasRequired = isLegacyVersion(safeVersion);
88
+ // For 1.3.0+ Safes safeTxGas is not required
89
+ if (!isSafeTxGasRequired)
90
+ return 0;
91
+ const address = toChecksumAddress(safeAddress);
92
+ try {
93
+ const estimation = await this.request.post(`/safes/${address}/multisig-transactions/estimations/`, {
94
+ to: toChecksumAddress(safeTxData.to),
95
+ value: +safeTxData.value || 0,
96
+ data: safeTxData.data,
97
+ operation: safeTxData.operation,
98
+ });
99
+ return Number(estimation.safeTxGas);
100
+ }
101
+ catch (e) {
102
+ console.error(e);
103
+ }
104
+ }
45
105
  }
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.6",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -21,6 +21,7 @@
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,54 @@ 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",
58
99
  };
59
100
 
60
101
  export default class RequestProvider {
@@ -63,14 +104,14 @@ export default class RequestProvider {
63
104
 
64
105
  constructor(networkId: string, adapter?: AxiosAdapter) {
65
106
  if (!(networkId in HOST_MAP)) {
66
- throw new Error('Wrong networkId');
107
+ throw new Error("Wrong networkId");
67
108
  }
68
109
 
69
110
  this.host = HOST_MAP[networkId];
70
111
 
71
112
  this.request = axios.create({
72
113
  baseURL: this.host,
73
- adapter
114
+ adapter,
74
115
  });
75
116
 
76
117
  this.request.interceptors.response.use((response) => {
@@ -87,8 +128,8 @@ export default class RequestProvider {
87
128
  {
88
129
  params: {
89
130
  executed: false,
90
- nonce__gte: nonce
91
- }
131
+ nonce__gte: nonce,
132
+ },
92
133
  }
93
134
  );
94
135
  }
@@ -110,4 +151,33 @@ export default class RequestProvider {
110
151
  data
111
152
  );
112
153
  }
154
+
155
+ // https://github.com/safe-global/safe-wallet-web/blob/dev/src/services/tx/tx-sender/recommendedNonce.ts#L24
156
+ async getSafeTxGas(
157
+ safeAddress: string,
158
+ safeVersion: string,
159
+ safeTxData: SafeTransactionDataPartial
160
+ ): Promise<number | undefined> {
161
+ const isSafeTxGasRequired = isLegacyVersion(safeVersion);
162
+
163
+ // For 1.3.0+ Safes safeTxGas is not required
164
+ if (!isSafeTxGasRequired) return 0;
165
+
166
+ const address = toChecksumAddress(safeAddress);
167
+
168
+ try {
169
+ const estimation: { safeTxGas: string } = await this.request.post(
170
+ `/safes/${address}/multisig-transactions/estimations/`,
171
+ {
172
+ to: toChecksumAddress(safeTxData.to),
173
+ value: +safeTxData.value || 0,
174
+ data: safeTxData.data,
175
+ operation: safeTxData.operation,
176
+ }
177
+ );
178
+ return Number(estimation.safeTxGas);
179
+ } catch (e) {
180
+ console.error(e);
181
+ }
182
+ }
113
183
  }
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