Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #21: Allow specifying safe tx gas #52

Merged
merged 11 commits into from
Oct 15, 2020
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ You can remove listeners by calling `appsSdk.removeListeners()`.

### Sending TXs

Sending a TX through the Safe Multisig is as simple as invoking `sendTransaction` method with an array of TXs.
Sending a TX through the Safe Multisig is as simple as invoking `sendTransactionsWithParams` method with an array of TXs.

```js
// Create a web3 instance
Expand All @@ -98,12 +98,16 @@ const txs = [
},
];

const params = {
safeTxGas: 500000,
};

// Send to Safe-multisig
const message = appsSdk.sendTransactions(txs);
const message = appsSdk.sendTransactionsWithParams(txs, params);
console.log(message.requestId);
```

`sendTransactions` returns a message containing the requestId. You can use it to map transaction calls with `onTransactionConfirmation` events.
`sendTransactionsWithParams` returns a message containing the requestId. You can use it to map transaction calls with `onTransactionConfirmation` events.

> Note: `value` accepts a number or a string as a decimal or hex number.

Expand Down
22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,22 @@
"author": "Gnosis (https://gnosis.pm)",
"license": "MIT",
"devDependencies": {
"@types/jest": "^26.0.13",
"@types/node": "^14.6.4",
"@typescript-eslint/eslint-plugin": "^4.1.0",
"@typescript-eslint/parser": "^4.1.0",
"eslint": "^7.8.1",
"eslint-config-prettier": "^6.11.0",
"@types/jest": "^26.0.14",
"@types/node": "^14.11.5",
"@typescript-eslint/eslint-plugin": "^4.4.0",
"@typescript-eslint/parser": "^4.4.0",
"eslint": "^7.10.0",
"eslint-config-prettier": "^6.12.0",
"eslint-plugin-prettier": "^3.1.4",
"husky": "^4.3.0",
"jest": "^26.4.2",
"lint-staged": "^10.3.0",
"prettier": "^2.1.1",
"jest": "^26.5.2",
"lint-staged": "^10.4.0",
"prettier": "^2.1.2",
"rimraf": "^3.0.2",
"ts-jest": "^26.3.0",
"ts-jest": "^26.4.1",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0",
"typescript": "^4.0.2"
"typescript": "^4.0.3"
},
"husky": {
"hooks": {
Expand Down
54 changes: 51 additions & 3 deletions src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import initSdk, { SdkInstance } from './index';
import initSdk, { SdkInstance, SEND_TRANSACTIONS_DEPRECATION_MSG } from './index';
import { SDK_MESSAGES } from './messageIds';

describe('safe app sdk', () => {
describe('Safe apps SDK', () => {
let sdkInstance: SdkInstance;

describe('initSdk', () => {
Expand All @@ -16,7 +16,18 @@ describe('safe app sdk', () => {
});
});

describe('sendTransaction', () => {
describe('sendTransactions', () => {
beforeEach(() => {
jest.spyOn(console, 'warn').mockImplementation(() => ({}));
});

test('Should display a deprecation message', () => {
const txs = [{ to: 'address', value: '0', data: '0x' }];
sdkInstance.sendTransactions(txs);

expect(console.warn).toHaveBeenCalledWith(SEND_TRANSACTIONS_DEPRECATION_MSG);
});

test('Should throw an error when passing an empty array', () => {
expect(() => {
sdkInstance.sendTransactions([]);
Expand All @@ -39,4 +50,41 @@ describe('safe app sdk', () => {
expect(request.data).toEqual(txs);
});
});

describe('sendTransactionsWithParams', () => {
test('Should throw an error when passing an empty array', () => {
expect(() => {
sdkInstance.sendTransactionsWithParams([]);
}).toThrow();
});

test('Should call window.parent.postMessage with a requestId when passing array of TXs', () => {
const requestId = '1000';
const spy = jest.spyOn(window.parent, 'postMessage');
const txs = [{ to: 'address', value: '0', data: '0x' }];
sdkInstance.sendTransactionsWithParams(txs, undefined, requestId);
expect(spy).toHaveBeenCalledWith(
{ messageId: SDK_MESSAGES.SEND_TRANSACTIONS_V2, data: { txs, params: undefined }, requestId },
'*',
);
});

test('Should return a message containing requestId', () => {
const txs = [{ to: 'address', value: '0', data: '0x' }];
const request = sdkInstance.sendTransactionsWithParams(txs);

expect(typeof request.requestId).toBe('number');
expect(request.data).toEqual({ txs });
});

test('Should include passed safeTxGas and requestId params to a message body', () => {
const txs = [{ to: 'address', value: '0', data: '0x' }];
const requestId = 1234;
const params = { safeTxGas: 5000 };
const request = sdkInstance.sendTransactionsWithParams(txs, params, requestId);

expect(request.requestId).toBe(requestId);
expect(request.data).toEqual({ txs, params });
});
});
});
31 changes: 30 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
SentSDKMessage,
RequestId,
InterfaceMessageToPayload,
SendTransactionParams,
} from './types';
import { INTERFACE_MESSAGES, SDK_MESSAGES } from './messageIds';
import { txs as txsMethods, setTxServiceUrl } from './txs';
Expand All @@ -19,6 +20,10 @@ const config: {
listeners?: SafeListeners;
} = {};

export const SEND_TRANSACTIONS_DEPRECATION_MSG = `sendTransactions will be deprecated in the next major release. Please use sendTransactionsWithParams method instead.
Check the docs at https://github.com/gnosis/safe-apps-sdk
`;

const _logMessageFromSafe = (origin: string, messageId: InterfaceMessageIds): void => {
console.info(`SafeConnector: A message with id ${messageId} was received from origin ${origin}.`);
};
Expand Down Expand Up @@ -155,6 +160,7 @@ function removeListeners(): void {
* @param txs
*/
function sendTransactions(txs: Transaction[], requestId?: RequestId): SentSDKMessage<'SEND_TRANSACTIONS'> {
console.warn(SEND_TRANSACTIONS_DEPRECATION_MSG);
if (!txs || !txs.length) {
throw new Error('sendTransactions: No transactions were passed');
}
Expand All @@ -164,6 +170,29 @@ function sendTransactions(txs: Transaction[], requestId?: RequestId): SentSDKMes
return message;
}

/**
* Request Safe app to send transactions
* @param txs
*/
function sendTransactionsWithParams(
mmv08 marked this conversation as resolved.
Show resolved Hide resolved
txs: Transaction[],
params?: SendTransactionParams,
requestId?: RequestId,
): SentSDKMessage<'SEND_TRANSACTIONS_V2'> {
if (!txs || !txs.length) {
throw new Error('sendTransactions: No transactions were passed');
mmv08 marked this conversation as resolved.
Show resolved Hide resolved
}

const messagePayload = {
txs,
params,
};

const message = _sendMessageToParent(SDK_MESSAGES.SEND_TRANSACTIONS_V2, messagePayload, requestId);

return message;
}

/**
* Sets Safe-app url that will render the third-party app.
* @param parentUrl
Expand All @@ -176,7 +205,7 @@ function initSdk(safeAppUrlsRegExp: RegExp[] = []): SdkInstance {
];
sendInitializationMessage();

return { addListeners, removeListeners, sendTransactions, txs: txsMethods };
return { addListeners, removeListeners, sendTransactions, sendTransactionsWithParams, txs: txsMethods };
}

export default initSdk;
Expand Down
1 change: 1 addition & 0 deletions src/messageIds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export const INTERFACE_MESSAGES = {
export const SDK_MESSAGES = {
SAFE_APP_SDK_INITIALIZED: 'SAFE_APP_SDK_INITIALIZED',
SEND_TRANSACTIONS: 'SEND_TRANSACTIONS',
SEND_TRANSACTIONS_V2: 'SEND_TRANSACTIONS_V2',
} as const;
13 changes: 13 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,19 @@ export interface Transaction {

export type RequestId = number | string;

export interface SendTransactionParams {
safeTxGas?: number;
}

export interface SdkInstance {
addListeners: (listeners: SafeListeners) => void;
removeListeners: () => void;
sendTransactions: (txs: Transaction[], requestId?: RequestId) => SentSDKMessage<'SEND_TRANSACTIONS'>;
sendTransactionsWithParams: (
txs: Transaction[],
params?: SendTransactionParams,
requestId?: RequestId,
) => SentSDKMessage<'SEND_TRANSACTIONS_V2'>;
txs: typeof txs;
}

Expand Down Expand Up @@ -59,6 +68,10 @@ export interface InterfaceMessageEvent extends MessageEvent {
export interface SDKMessageToPayload {
[SDK_MESSAGES.SAFE_APP_SDK_INITIALIZED]: undefined;
[SDK_MESSAGES.SEND_TRANSACTIONS]: Transaction[];
[SDK_MESSAGES.SEND_TRANSACTIONS_V2]: {
txs: Transaction[];
params?: SendTransactionParams;
};
}

export type SDKMessageIds = keyof typeof SDK_MESSAGES;
Expand Down
Loading