@rabby-wallet/gnosis-sdk 1.0.0 → 1.1.0

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 ADDED
@@ -0,0 +1,54 @@
1
+ import { Axios } from "axios";
2
+ export interface SafeInfo {
3
+ address: string;
4
+ fallbackHandler: string;
5
+ guard: string;
6
+ masterCopy: string;
7
+ modules: string[];
8
+ nonce: number;
9
+ owners: string[];
10
+ threshold: number;
11
+ version: string;
12
+ }
13
+ interface ConfirmationItem {
14
+ owner: string;
15
+ submissionDate: string;
16
+ transactionHash: string | null;
17
+ signature: string;
18
+ signatureType: string;
19
+ }
20
+ export interface SafeTransactionItem {
21
+ safe: string;
22
+ to: string;
23
+ value: string;
24
+ data: string | null;
25
+ operation: number;
26
+ gasToken: string;
27
+ safeTxGas: number;
28
+ baseGas: number;
29
+ gasPrice: string;
30
+ refundReceiver: string;
31
+ nonce: number;
32
+ executionDate: string | null;
33
+ submissionDate: string;
34
+ modified: string;
35
+ blockNumber: number | null;
36
+ transactionHash: string | null;
37
+ safeTxHash: string;
38
+ executor: string | null;
39
+ isExecuted: boolean;
40
+ confirmations: ConfirmationItem[];
41
+ signatures: string | null;
42
+ }
43
+ export default class RequestProvider {
44
+ host: string;
45
+ request: Axios;
46
+ constructor(networkId: string);
47
+ getPendingTransactions(safeAddress: string, nonce: number): Promise<{
48
+ results: SafeTransactionItem[];
49
+ }>;
50
+ postTransactions(safeAddres: string, data: any): Promise<void>;
51
+ getSafeInfo(safeAddress: string): Promise<SafeInfo>;
52
+ confirmTransaction(hash: string, data: any): Promise<void>;
53
+ }
54
+ export {};
package/dist/api.js ADDED
@@ -0,0 +1,39 @@
1
+ import axios from "axios";
2
+ import { toChecksumAddress } from "web3-utils";
3
+ const HOST_MAP = {
4
+ '1': "https://safe-transaction.gnosis.io/api/v1",
5
+ '137': 'https://safe-transaction.polygon.gnosis.io/api/v1',
6
+ '56': 'https://safe-transaction.bsc.gnosis.io/api/v1',
7
+ '100': 'https://safe-transaction.xdai.gnosis.io/api/v1'
8
+ };
9
+ export default class RequestProvider {
10
+ constructor(networkId) {
11
+ if (!(networkId in HOST_MAP)) {
12
+ throw new Error('Wrong networkId');
13
+ }
14
+ this.host = HOST_MAP[networkId];
15
+ this.request = axios.create({
16
+ baseURL: this.host
17
+ });
18
+ this.request.interceptors.response.use((response) => {
19
+ return response.data;
20
+ });
21
+ }
22
+ getPendingTransactions(safeAddress, nonce) {
23
+ return this.request.get(`/safes/${safeAddress}/multisig-transactions/`, {
24
+ params: {
25
+ executed: false,
26
+ nonce__gte: nonce,
27
+ },
28
+ });
29
+ }
30
+ postTransactions(safeAddres, data) {
31
+ return this.request.post(`/safes/${toChecksumAddress(safeAddres)}/multisig-transactions/`, data);
32
+ }
33
+ getSafeInfo(safeAddress) {
34
+ return this.request.get(`/safes/${safeAddress}/`);
35
+ }
36
+ confirmTransaction(hash, data) {
37
+ return this.request.post(`/multisig-transactions/${hash}/confirmations/`, data);
38
+ }
39
+ }
@@ -0,0 +1,3 @@
1
+ export declare const ZERO_ADDRESS: string;
2
+ export declare const EMPTY_DATA = "0x";
3
+ export declare const SENTINEL_ADDRESS = "0x0000000000000000000000000000000000000001";
@@ -0,0 +1,3 @@
1
+ export const ZERO_ADDRESS = `0x${"0".repeat(40)}`;
2
+ export const EMPTY_DATA = "0x";
3
+ export const SENTINEL_ADDRESS = "0x0000000000000000000000000000000000000001";
@@ -0,0 +1,36 @@
1
+ import { Contract } from "ethers";
2
+ import { BigNumber } from "@ethersproject/bignumber";
3
+ import { providers } from "ethers";
4
+ import { SafeTransactionDataPartial, SafeSignature } from "@gnosis.pm/safe-core-sdk-types";
5
+ import { TransactionResult, TransactionOptions } from "@gnosis.pm/safe-core-sdk/dist/src/utils/transactions/types";
6
+ import SafeTransaction from "@gnosis.pm/safe-core-sdk/dist/src/utils/transactions/SafeTransaction";
7
+ import RequestProvider, { SafeInfo } from "./api";
8
+ declare class Safe {
9
+ contract: Contract;
10
+ safeAddress: string;
11
+ owners: string[];
12
+ version: string;
13
+ provider: providers.Web3Provider;
14
+ safeInfo: SafeInfo | null;
15
+ request: RequestProvider;
16
+ network: string;
17
+ constructor(safeAddress: string, version: string, provider: providers.Web3Provider, network?: string);
18
+ static getSafeInfo(safeAddress: string, network: string): Promise<SafeInfo>;
19
+ static getPendingTransactions(safeAddress: string, network: string): Promise<{
20
+ results: import("./api").SafeTransactionItem[];
21
+ }>;
22
+ init(): Promise<void>;
23
+ getOwners(): Promise<string[]>;
24
+ getThreshold(): Promise<any>;
25
+ getNonce(): Promise<number>;
26
+ buildTransaction(data: SafeTransactionDataPartial): Promise<SafeTransaction>;
27
+ getTransactionHash(transaction: SafeTransaction): Promise<any>;
28
+ signTransactionHash(hash: string): Promise<SafeSignature>;
29
+ signTransaction(transaction: SafeTransaction): Promise<void>;
30
+ getOwnersWhoApprovedTx(txHash: string): Promise<string[]>;
31
+ postTransaction(transaction: SafeTransaction, hash: string): Promise<void>;
32
+ confirmTransaction(safeTransaction: SafeTransaction): Promise<void>;
33
+ getBalance(): Promise<BigNumber>;
34
+ executeTransaction(safeTransaction: SafeTransaction, options?: TransactionOptions): Promise<TransactionResult>;
35
+ }
36
+ export default Safe;
package/dist/index.js ADDED
@@ -0,0 +1,163 @@
1
+ import { Contract } from "ethers";
2
+ import { BigNumber } from "@ethersproject/bignumber";
3
+ import BN from 'bignumber.js';
4
+ import { getSafeSingletonDeployment } from "@gnosis.pm/safe-deployments";
5
+ import { toChecksumAddress } from "web3-utils";
6
+ import SafeTransaction from "@gnosis.pm/safe-core-sdk/dist/src/utils/transactions/SafeTransaction";
7
+ import RequestProvider from "./api";
8
+ import { standardizeSafeTransactionData, sameString, generateSignature, generatePreValidatedSignature, estimateGasForTransactionExecution, } from "./utils";
9
+ class Safe {
10
+ constructor(safeAddress, version, provider, network = "1") {
11
+ this.owners = [];
12
+ this.safeInfo = null;
13
+ const contract = getSafeSingletonDeployment({
14
+ version,
15
+ network,
16
+ });
17
+ if (!contract) {
18
+ throw new Error("Wrong version or network");
19
+ }
20
+ this.provider = provider;
21
+ this.contract = new Contract(safeAddress, contract.abi, this.provider);
22
+ this.version = version;
23
+ this.safeAddress = safeAddress;
24
+ this.network = network;
25
+ this.request = new RequestProvider(network);
26
+ this.init();
27
+ }
28
+ static getSafeInfo(safeAddress, network) {
29
+ const request = new RequestProvider(network);
30
+ return request.getSafeInfo(toChecksumAddress(safeAddress));
31
+ }
32
+ static async getPendingTransactions(safeAddress, network) {
33
+ const request = new RequestProvider(network);
34
+ const nonce = (await request.getSafeInfo(toChecksumAddress(safeAddress))).nonce;
35
+ const transactions = await request.getPendingTransactions(safeAddress, nonce);
36
+ return transactions;
37
+ }
38
+ async init() {
39
+ const safeInfo = await Safe.getSafeInfo(this.safeAddress, this.network);
40
+ this.safeInfo = safeInfo;
41
+ if (this.version !== safeInfo.version) {
42
+ throw new Error(`Current version ${this.version} not matched address version ${safeInfo.version}`);
43
+ }
44
+ this.version = safeInfo.version;
45
+ this.owners = safeInfo.owners;
46
+ }
47
+ async getOwners() {
48
+ const owners = await this.contract.getOwners();
49
+ return owners;
50
+ }
51
+ async getThreshold() {
52
+ const threshold = await this.contract.getThreshold();
53
+ return threshold.toNumber();
54
+ }
55
+ async getNonce() {
56
+ const nonce = await this.contract.nonce();
57
+ return nonce.toNumber();
58
+ }
59
+ async buildTransaction(data) {
60
+ const transaction = await standardizeSafeTransactionData(this.safeAddress, this.contract, this.provider, data);
61
+ return new SafeTransaction(transaction);
62
+ }
63
+ async getTransactionHash(transaction) {
64
+ const transactionData = transaction.data;
65
+ return this.contract.getTransactionHash(transactionData.to, transactionData.value, transactionData.data, transactionData.operation, transactionData.safeTxGas, transactionData.baseGas, transactionData.gasPrice, transactionData.gasToken, transactionData.refundReceiver, transactionData.nonce);
66
+ }
67
+ async signTransactionHash(hash) {
68
+ const owners = await this.getOwners();
69
+ const signer = await this.provider.getSigner(0);
70
+ const signerAddress = await signer.getAddress();
71
+ const addressIsOwner = owners.find((owner) => signerAddress && sameString(owner, signerAddress));
72
+ if (!addressIsOwner) {
73
+ throw new Error("Transactions can only be signed by Safe owners");
74
+ }
75
+ return generateSignature(this.provider, hash);
76
+ }
77
+ async signTransaction(transaction) {
78
+ const hash = await this.getTransactionHash(transaction);
79
+ const sig = await this.signTransactionHash(hash);
80
+ transaction.addSignature(sig);
81
+ }
82
+ async getOwnersWhoApprovedTx(txHash) {
83
+ const owners = await this.getOwners();
84
+ let ownersWhoApproved = [];
85
+ for (const owner of owners) {
86
+ const approved = await this.contract.approvedHashes(owner, txHash);
87
+ if (approved.gt(0)) {
88
+ ownersWhoApproved.push(owner);
89
+ }
90
+ }
91
+ return ownersWhoApproved;
92
+ }
93
+ async postTransaction(transaction, hash) {
94
+ const signer = this.provider.getSigner(0);
95
+ const signerAddress = await signer.getAddress();
96
+ const safeAddress = toChecksumAddress(this.safeAddress);
97
+ await this.request.postTransactions(this.safeAddress, {
98
+ safe: safeAddress,
99
+ to: toChecksumAddress(transaction.data.to),
100
+ value: new BN(transaction.data.value).toFixed(),
101
+ data: transaction.data.data,
102
+ operation: transaction.data.operation,
103
+ gasToken: transaction.data.gasToken,
104
+ safeTxGas: transaction.data.safeTxGas,
105
+ baseGas: transaction.data.baseGas,
106
+ gasPrice: transaction.data.gasPrice,
107
+ refundReceiver: transaction.data.refundReceiver,
108
+ nonce: transaction.data.nonce,
109
+ contractTransactionHash: hash,
110
+ sender: toChecksumAddress(signerAddress),
111
+ signature: transaction.encodedSignatures(),
112
+ });
113
+ }
114
+ async confirmTransaction(safeTransaction) {
115
+ const hash = await this.getTransactionHash(safeTransaction);
116
+ const signature = await this.signTransactionHash(hash);
117
+ safeTransaction.addSignature(signature);
118
+ const signer = await this.provider.getSigner(0);
119
+ const signerAddress = await signer.getAddress();
120
+ const sig = safeTransaction.signatures.get(signerAddress === null || signerAddress === void 0 ? void 0 : signerAddress.toLowerCase());
121
+ if (sig) {
122
+ await this.request.confirmTransaction(hash, { signature: sig.data });
123
+ }
124
+ }
125
+ async getBalance() {
126
+ return this.provider.getBalance(this.safeAddress);
127
+ }
128
+ async executeTransaction(safeTransaction, options) {
129
+ const txHash = await this.getTransactionHash(safeTransaction);
130
+ const ownersWhoApprovedTx = await this.getOwnersWhoApprovedTx(txHash);
131
+ for (const owner of ownersWhoApprovedTx) {
132
+ safeTransaction.addSignature(generatePreValidatedSignature(owner));
133
+ }
134
+ const owners = await this.getOwners();
135
+ const signer = await this.provider.getSigner(0);
136
+ const contract = this.contract.connect(signer);
137
+ const signerAddress = await signer.getAddress();
138
+ if (owners.includes(signerAddress)) {
139
+ safeTransaction.addSignature(generatePreValidatedSignature(signerAddress));
140
+ }
141
+ const threshold = await this.getThreshold();
142
+ if (threshold > safeTransaction.signatures.size) {
143
+ const signaturesMissing = threshold - safeTransaction.signatures.size;
144
+ throw new Error(`There ${signaturesMissing > 1 ? "are" : "is"} ${signaturesMissing} signature${signaturesMissing > 1 ? "s" : ""} missing`);
145
+ }
146
+ const value = BigNumber.from(safeTransaction.data.value);
147
+ if (!value.isZero()) {
148
+ const balance = await this.getBalance();
149
+ if (value.gt(BigNumber.from(balance))) {
150
+ throw new Error("Not enough Ether funds");
151
+ }
152
+ }
153
+ const gasLimit = await estimateGasForTransactionExecution(contract, signerAddress, safeTransaction);
154
+ const executionOptions = {
155
+ gasLimit,
156
+ gasPrice: options === null || options === void 0 ? void 0 : options.gasPrice,
157
+ from: signerAddress,
158
+ };
159
+ const txResponse = await contract.execTransaction(safeTransaction.data.to, safeTransaction.data.value, safeTransaction.data.data, safeTransaction.data.operation, safeTransaction.data.safeTxGas, safeTransaction.data.baseGas, safeTransaction.data.gasPrice, safeTransaction.data.gasToken, safeTransaction.data.refundReceiver, safeTransaction.encodedSignatures(), executionOptions);
160
+ return txResponse;
161
+ }
162
+ }
163
+ export default Safe;
package/dist/type.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { BigNumber } from "@ethersproject/bignumber";
2
+ import { SafeTransaction, SafeTransactionData } from "@gnosis.pm/safe-core-sdk-types";
3
+ import { TransactionOptions, TransactionResult } from "@gnosis.pm/safe-core-sdk/dist/src/utils/transactions/types";
4
+ export interface GnosisSafeContract {
5
+ getVersion(): Promise<string>;
6
+ getAddress(): string;
7
+ getNonce(): Promise<number>;
8
+ getThreshold(): Promise<number>;
9
+ getOwners(): Promise<string[]>;
10
+ isOwner(address: string): Promise<boolean>;
11
+ getTransactionHash(safeTransactionData: SafeTransactionData): Promise<string>;
12
+ approvedHashes(ownerAddress: string, hash: string): Promise<BigNumber>;
13
+ approveHash(hash: string, options?: TransactionOptions): Promise<TransactionResult>;
14
+ getModules(): Promise<string[]>;
15
+ isModuleEnabled(moduleAddress: string): Promise<boolean>;
16
+ execTransaction(safeTransaction: SafeTransaction, options?: TransactionOptions): Promise<TransactionResult>;
17
+ encode(methodName: any, params: any): string;
18
+ estimateGas(methodName: string, params: any[], options: TransactionOptions): Promise<number>;
19
+ }
package/dist/type.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { Contract, providers } from "ethers";
2
+ import { OperationType, SafeTransactionData, SafeTransactionDataPartial, SafeSignature, SafeTransaction } from "@gnosis.pm/safe-core-sdk-types";
3
+ import EthSignSignature from "@gnosis.pm/safe-core-sdk/dist/src/utils/signatures/SafeSignature";
4
+ export declare function sameString(str1: string, str2: string): boolean;
5
+ export declare function isRestrictedAddress(address: string): boolean;
6
+ 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 generatePreValidatedSignature(ownerAddress: string): SafeSignature;
9
+ export declare function isTxHashSignedWithPrefix(txHash: string, signature: string, ownerAddress: string): boolean;
10
+ export declare function adjustVInSignature(signature: string, hasPrefix: boolean): string;
11
+ export declare function generateSignature(provider: providers.Web3Provider, hash: string): Promise<EthSignSignature>;
12
+ export declare function estimateGasForTransactionExecution(safeContract: Contract, from: string, tx: SafeTransaction): Promise<number>;
package/dist/utils.js ADDED
@@ -0,0 +1,156 @@
1
+ import { BigNumber } from "@ethersproject/bignumber";
2
+ import { OperationType, } from "@gnosis.pm/safe-core-sdk-types";
3
+ import { bufferToHex, ecrecover, pubToAddress } from "ethereumjs-util";
4
+ import { ZERO_ADDRESS, SENTINEL_ADDRESS } from "./constants";
5
+ import EthSignSignature from "@gnosis.pm/safe-core-sdk/dist/src/utils/signatures/SafeSignature";
6
+ function estimateDataGasCosts(data) {
7
+ const reducer = (accumulator, currentValue) => {
8
+ if (currentValue === "0x") {
9
+ return accumulator + 0;
10
+ }
11
+ if (currentValue === "00") {
12
+ return accumulator + 4;
13
+ }
14
+ return accumulator + 16;
15
+ };
16
+ return data.match(/.{2}/g).reduce(reducer, 0);
17
+ }
18
+ export function sameString(str1, str2) {
19
+ return str1.toLowerCase() === str2.toLowerCase();
20
+ }
21
+ function isZeroAddress(address) {
22
+ return address === ZERO_ADDRESS;
23
+ }
24
+ function isSentinelAddress(address) {
25
+ return address === SENTINEL_ADDRESS;
26
+ }
27
+ export function isRestrictedAddress(address) {
28
+ return isZeroAddress(address) || isSentinelAddress(address);
29
+ }
30
+ export async function estimateTxGas(safeAddress, safeContract, provider, to, valueInWei, data, operation) {
31
+ let txGasEstimation = 0;
32
+ const estimateData = safeContract.interface.encodeFunctionData("requiredTxGas", [to, valueInWei, data, operation]);
33
+ try {
34
+ const estimateResponse = (await provider.estimateGas({
35
+ to: safeAddress,
36
+ from: safeAddress,
37
+ data: estimateData,
38
+ })).toString();
39
+ txGasEstimation =
40
+ BigNumber.from("0x" + estimateResponse.substring(138)).toNumber() + 10000;
41
+ }
42
+ catch (error) { }
43
+ if (txGasEstimation > 0) {
44
+ const dataGasEstimation = estimateDataGasCosts(estimateData);
45
+ let additionalGas = 10000;
46
+ for (let i = 0; i < 10; i++) {
47
+ try {
48
+ const estimateResponse = await provider.call({
49
+ to: safeAddress,
50
+ from: safeAddress,
51
+ data: estimateData,
52
+ gasPrice: 0,
53
+ gasLimit: txGasEstimation + dataGasEstimation + additionalGas,
54
+ });
55
+ if (estimateResponse !== "0x") {
56
+ break;
57
+ }
58
+ }
59
+ catch (error) { }
60
+ txGasEstimation += additionalGas;
61
+ additionalGas *= 2;
62
+ }
63
+ return txGasEstimation + additionalGas;
64
+ }
65
+ try {
66
+ const estimateGas = await provider.estimateGas({
67
+ to,
68
+ from: safeAddress,
69
+ value: valueInWei,
70
+ data,
71
+ });
72
+ return estimateGas.toNumber();
73
+ }
74
+ catch (error) {
75
+ if (operation === OperationType.DelegateCall) {
76
+ return 0;
77
+ }
78
+ return Promise.reject(error);
79
+ }
80
+ }
81
+ export async function standardizeSafeTransactionData(safeAddress, safeContract, provider, tx) {
82
+ var _a, _b, _c, _d, _e;
83
+ const standardizedTxs = {
84
+ to: tx.to,
85
+ value: tx.value,
86
+ data: tx.data,
87
+ operation: (_a = tx.operation) !== null && _a !== void 0 ? _a : OperationType.Call,
88
+ baseGas: (_b = tx.baseGas) !== null && _b !== void 0 ? _b : 0,
89
+ gasPrice: (_c = tx.gasPrice) !== null && _c !== void 0 ? _c : 0,
90
+ gasToken: tx.gasToken || ZERO_ADDRESS,
91
+ refundReceiver: tx.refundReceiver || ZERO_ADDRESS,
92
+ nonce: (_d = tx.nonce) !== null && _d !== void 0 ? _d : (await safeContract.nonce()).toNumber(),
93
+ };
94
+ const safeTxGas = (_e = tx.safeTxGas) !== null && _e !== void 0 ? _e : (await estimateTxGas(safeAddress, safeContract, provider, standardizedTxs.to, standardizedTxs.value, standardizedTxs.data, standardizedTxs.operation));
95
+ return {
96
+ ...standardizedTxs,
97
+ safeTxGas,
98
+ };
99
+ }
100
+ export function generatePreValidatedSignature(ownerAddress) {
101
+ const signature = "0x000000000000000000000000" +
102
+ ownerAddress.slice(2) +
103
+ "0000000000000000000000000000000000000000000000000000000000000000" +
104
+ "01";
105
+ return new EthSignSignature(ownerAddress, signature);
106
+ }
107
+ export function isTxHashSignedWithPrefix(txHash, signature, ownerAddress) {
108
+ let hasPrefix;
109
+ try {
110
+ const rsvSig = {
111
+ r: Buffer.from(signature.slice(2, 66), "hex"),
112
+ s: Buffer.from(signature.slice(66, 130), "hex"),
113
+ v: parseInt(signature.slice(130, 132), 16),
114
+ };
115
+ const recoveredData = ecrecover(Buffer.from(txHash.slice(2), "hex"), rsvSig.v, rsvSig.r, rsvSig.s);
116
+ const recoveredAddress = bufferToHex(pubToAddress(recoveredData));
117
+ hasPrefix = !sameString(recoveredAddress, ownerAddress);
118
+ }
119
+ catch (e) {
120
+ hasPrefix = true;
121
+ }
122
+ return hasPrefix;
123
+ }
124
+ export function adjustVInSignature(signature, hasPrefix) {
125
+ const V_VALUES = [0, 1, 27, 28];
126
+ const MIN_VALID_V_VALUE = 27;
127
+ let signatureV = parseInt(signature.slice(-2), 16);
128
+ if (!V_VALUES.includes(signatureV)) {
129
+ throw new Error("Invalid signature");
130
+ }
131
+ if (signatureV < MIN_VALID_V_VALUE) {
132
+ signatureV += MIN_VALID_V_VALUE;
133
+ }
134
+ if (hasPrefix) {
135
+ signatureV += 4;
136
+ }
137
+ signature = signature.slice(0, -2) + signatureV.toString(16);
138
+ return signature;
139
+ }
140
+ export async function generateSignature(provider, hash) {
141
+ const signer = await provider.getSigner(0);
142
+ const signerAddress = await signer.getAddress();
143
+ let signature = await provider.send("personal_sign", [hash, signerAddress]);
144
+ const hasPrefix = isTxHashSignedWithPrefix(hash, signature, signerAddress);
145
+ signature = adjustVInSignature(signature, hasPrefix);
146
+ return new EthSignSignature(signerAddress, signature);
147
+ }
148
+ export async function estimateGasForTransactionExecution(safeContract, from, tx) {
149
+ try {
150
+ const gas = await safeContract.estimateGas.execTransaction(tx.data.to, tx.data.value, tx.data.data, tx.data.operation, tx.data.safeTxGas, tx.data.baseGas, tx.data.gasPrice, tx.data.gasToken, tx.data.refundReceiver, tx.encodedSignatures(), { from });
151
+ return gas.toNumber();
152
+ }
153
+ catch (error) {
154
+ return Promise.reject(error);
155
+ }
156
+ }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@rabby-wallet/gnosis-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "",
5
- "main": "index.js",
5
+ "main": "dist/index.js",
6
6
  "scripts": {
7
7
  "build": "tsc"
8
8
  },
@@ -18,6 +18,7 @@
18
18
  "@gnosis.pm/safe-core-sdk-types": "^0.1.1",
19
19
  "@gnosis.pm/safe-deployments": "^1.4.0",
20
20
  "axios": "^0.24.0",
21
+ "bignumber.js": "^9.0.2",
21
22
  "ethereumjs-util": "^7.1.3",
22
23
  "ethers": "^5.5.1",
23
24
  "typescript": "^4.4.4",
package/src/api.ts CHANGED
@@ -21,7 +21,7 @@ interface ConfirmationItem {
21
21
  signatureType: string;
22
22
  }
23
23
 
24
- interface SafeTransactionItem {
24
+ export interface SafeTransactionItem {
25
25
  safe: string;
26
26
  to: string;
27
27
  value: string;
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Contract } from "ethers";
2
2
  import { BigNumber } from "@ethersproject/bignumber";
3
+ import BN from 'bignumber.js';
3
4
  import { getSafeSingletonDeployment } from "@gnosis.pm/safe-deployments";
4
5
  import { providers } from "ethers";
5
6
  import { toChecksumAddress } from "web3-utils";
@@ -19,7 +20,6 @@ import {
19
20
  generateSignature,
20
21
  generatePreValidatedSignature,
21
22
  estimateGasForTransactionExecution,
22
- toTxResult,
23
23
  } from "./utils";
24
24
 
25
25
  class Safe {
@@ -56,7 +56,18 @@ class Safe {
56
56
 
57
57
  static getSafeInfo(safeAddress: string, network: string) {
58
58
  const request = new RequestProvider(network);
59
- return request.getSafeInfo(safeAddress);
59
+ return request.getSafeInfo(toChecksumAddress(safeAddress));
60
+ }
61
+
62
+ static async getPendingTransactions(safeAddress: string, network: string) {
63
+ const request = new RequestProvider(network);
64
+ const nonce = (await request.getSafeInfo(toChecksumAddress(safeAddress))).nonce;
65
+ const transactions = await request.getPendingTransactions(
66
+ safeAddress,
67
+ nonce
68
+ );
69
+
70
+ return transactions;
60
71
  }
61
72
 
62
73
  async init() {
@@ -87,13 +98,6 @@ class Safe {
87
98
  return nonce.toNumber();
88
99
  }
89
100
 
90
- async getPendingTransactions() {
91
- const nonce = await this.getNonce();
92
- const transactions = await this.request.getPendingTransactions(this.safeAddress, nonce);
93
-
94
- return transactions;
95
- }
96
-
97
101
  async buildTransaction(data: SafeTransactionDataPartial) {
98
102
  const transaction = await standardizeSafeTransactionData(
99
103
  this.safeAddress,
@@ -158,7 +162,7 @@ class Safe {
158
162
  await this.request.postTransactions(this.safeAddress, {
159
163
  safe: safeAddress,
160
164
  to: toChecksumAddress(transaction.data.to),
161
- value: Number(transaction.data.value),
165
+ value: new BN(transaction.data.value).toFixed(),
162
166
  data: transaction.data.data,
163
167
  operation: transaction.data.operation,
164
168
  gasToken: transaction.data.gasToken,
@@ -251,9 +255,9 @@ class Safe {
251
255
  safeTransaction.data.refundReceiver,
252
256
  safeTransaction.encodedSignatures(),
253
257
  executionOptions
254
- )
258
+ );
255
259
 
256
- return toTxResult(txResponse, executionOptions);
260
+ return txResponse;
257
261
  }
258
262
  }
259
263
 
package/src/utils.ts CHANGED
@@ -1,18 +1,12 @@
1
1
  import { BigNumber } from "@ethersproject/bignumber";
2
2
  import { Contract, providers } from "ethers";
3
3
  import {
4
- MetaTransactionData,
5
4
  OperationType,
6
5
  SafeTransactionData,
7
6
  SafeTransactionDataPartial,
8
7
  SafeSignature,
9
8
  SafeTransaction,
10
9
  } from "@gnosis.pm/safe-core-sdk-types";
11
- import {
12
- TransactionOptions,
13
- Web3TransactionResult,
14
- } from "@gnosis.pm/safe-core-sdk/dist/src/utils/transactions/types";
15
- import { PromiEvent, TransactionReceipt } from "web3-core/types";
16
10
  import { bufferToHex, ecrecover, pubToAddress } from "ethereumjs-util";
17
11
  import { ZERO_ADDRESS, SENTINEL_ADDRESS } from "./constants";
18
12
  import EthSignSignature from "@gnosis.pm/safe-core-sdk/dist/src/utils/signatures/SafeSignature";
@@ -236,16 +230,3 @@ export async function estimateGasForTransactionExecution(
236
230
  return Promise.reject(error);
237
231
  }
238
232
  }
239
-
240
- export function toTxResult(
241
- promiEvent: PromiEvent<TransactionReceipt>,
242
- options?: TransactionOptions
243
- ): Promise<Web3TransactionResult> {
244
- return new Promise((resolve, reject) =>
245
- promiEvent
246
- .once("transactionHash", (hash: string) =>
247
- resolve({ hash, promiEvent, options })
248
- )
249
- .catch(reject)
250
- );
251
- }
package/tsconfig.json CHANGED
@@ -12,7 +12,8 @@
12
12
  "allowSyntheticDefaultImports": true,
13
13
  "allowJs": true,
14
14
  "plugins": [{ "transform": "typescript-transform-paths", "afterDeclarations": true }],
15
- "outDir": "./dist"
15
+ "outDir": "./dist",
16
+ "declaration": true
16
17
  },
17
18
  "exclude": ["./node_modules"],
18
19
  "include": ["src", "__tests__"]