Socket
Socket
Sign inDemoInstall

@safe-global/safe-apps-sdk

Package Overview
Dependencies
Maintainers
2
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@safe-global/safe-apps-sdk - npm Package Compare versions

Comparing version 7.11.0 to 8.0.0

dist/src/setupTests.d.ts

6

CHANGELOG.md
# @safe-global/safe-apps-sdk
## 8.0.0
### Major Changes
- dfb7fae: Optimized SDK bundle size by ~100kb
## 7.11.0

@@ -4,0 +10,0 @@

6

dist/package.json
{
"name": "@safe-global/safe-apps-sdk",
"version": "7.11.0",
"version": "8.0.0",
"description": "SDK developed to integrate third-party apps with Safe app.",

@@ -20,3 +20,3 @@ "main": "dist/src/index.js",

"test": "jest",
"format-dist": "sed -i '' 's/\"files\":/\"_files\":/' dist/package.json",
"format-dist": "sed -i 's/\"files\":/\"_files\":/' dist/package.json",
"build": "yarn rimraf dist && tsc && yarn format-dist"

@@ -28,3 +28,3 @@ },

"@safe-global/safe-gateway-typescript-sdk": "^3.5.3",
"ethers": "^5.7.2"
"viem": "^1.0.0"
},

@@ -31,0 +31,0 @@ "devDependencies": {

@@ -13,3 +13,3 @@ "use strict";

exports.Safe = void 0;
const ethers_1 = require("ethers");
const viem_1 = require("viem");
const signatures_1 = require("./signatures");

@@ -41,6 +41,31 @@ const methods_1 = require("../communication/methods");

const safeInfo = await this.getInfo();
const encodedIsValidSignatureCall = signatures_1.EIP_1271_INTERFACE.encodeFunctionData('isValidSignature', [
messageHash,
signature,
]);
const encodedIsValidSignatureCall = (0, viem_1.encodeFunctionData)({
abi: [
{
constant: false,
inputs: [
{
name: '_dataHash',
type: 'bytes32',
},
{
name: '_signature',
type: 'bytes',
},
],
name: 'isValidSignature',
outputs: [
{
name: '',
type: 'bytes4',
},
],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
},
],
functionName: 'isValidSignature',
args: [messageHash, signature],
});
const payload = {

@@ -66,7 +91,31 @@ call: constants_1.RPC_CALLS.eth_call,

const safeInfo = await this.getInfo();
const msgBytes = ethers_1.ethers.utils.arrayify(messageHash);
const encodedIsValidSignatureCall = signatures_1.EIP_1271_BYTES_INTERFACE.encodeFunctionData('isValidSignature', [
msgBytes,
signature,
]);
const encodedIsValidSignatureCall = (0, viem_1.encodeFunctionData)({
abi: [
{
constant: false,
inputs: [
{
name: '_data',
type: 'bytes',
},
{
name: '_signature',
type: 'bytes',
},
],
name: 'isValidSignature',
outputs: [
{
name: '',
type: 'bytes4',
},
],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
},
],
functionName: 'isValidSignature',
args: [messageHash, signature],
});
const payload = {

@@ -91,6 +140,23 @@ call: constants_1.RPC_CALLS.eth_call,

calculateMessageHash(message) {
return ethers_1.ethers.utils.hashMessage(message);
return (0, viem_1.hashMessage)(message);
}
calculateTypedMessageHash(typedMessage) {
return ethers_1.ethers.utils._TypedDataEncoder.hash(typedMessage.domain, typedMessage.types, typedMessage.message);
const chainId = typeof typedMessage.domain.chainId === 'object'
? typedMessage.domain.chainId.toNumber()
: Number(typedMessage.domain.chainId);
let primaryType = typedMessage.primaryType;
if (!primaryType) {
const fields = Object.values(typedMessage.types);
// We try to infer primaryType (simplified ether's version)
const primaryTypes = Object.keys(typedMessage.types).filter((typeName) => fields.every((dataTypes) => dataTypes.every(({ type }) => type.replace('[', '').replace(']', '') !== typeName)));
if (primaryTypes.length === 0 || primaryTypes.length > 1)
throw new Error('Please specify primaryType');
primaryType = primaryTypes[0];
}
return (0, viem_1.hashTypedData)({
message: typedMessage.message,
domain: Object.assign(Object.assign({}, typedMessage.domain), { chainId, verifyingContract: typedMessage.domain.verifyingContract, salt: typedMessage.domain.salt }),
types: typedMessage.types,
primaryType,
});
}

@@ -97,0 +163,0 @@ async getOffChainSignature(messageHash) {

@@ -1,6 +0,3 @@

import { ethers } from 'ethers';
declare const MAGIC_VALUE = "0x1626ba7e";
declare const MAGIC_VALUE_BYTES = "0x20c13b0b";
declare const EIP_1271_INTERFACE: ethers.utils.Interface;
declare const EIP_1271_BYTES_INTERFACE: ethers.utils.Interface;
export { EIP_1271_INTERFACE, EIP_1271_BYTES_INTERFACE, MAGIC_VALUE, MAGIC_VALUE_BYTES };
export { MAGIC_VALUE, MAGIC_VALUE_BYTES };
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MAGIC_VALUE_BYTES = exports.MAGIC_VALUE = exports.EIP_1271_BYTES_INTERFACE = exports.EIP_1271_INTERFACE = void 0;
const ethers_1 = require("ethers");
exports.MAGIC_VALUE_BYTES = exports.MAGIC_VALUE = void 0;
const MAGIC_VALUE = '0x1626ba7e';

@@ -9,10 +8,2 @@ exports.MAGIC_VALUE = MAGIC_VALUE;

exports.MAGIC_VALUE_BYTES = MAGIC_VALUE_BYTES;
const EIP_1271_INTERFACE = new ethers_1.ethers.utils.Interface([
'function isValidSignature(bytes32 _dataHash, bytes calldata _signature) external view',
]);
exports.EIP_1271_INTERFACE = EIP_1271_INTERFACE;
const EIP_1271_BYTES_INTERFACE = new ethers_1.ethers.utils.Interface([
'function isValidSignature(bytes calldata _data, bytes calldata _signature) public view',
]);
exports.EIP_1271_BYTES_INTERFACE = EIP_1271_BYTES_INTERFACE;
//# sourceMappingURL=signatures.js.map
import { ChainInfo as _ChainInfo } from '@safe-global/safe-gateway-typescript-sdk';
import { BigNumberish, BytesLike } from 'ethers';
export type ChainInfo = Pick<_ChainInfo, 'chainName' | 'chainId' | 'shortName' | 'nativeCurrency' | 'blockExplorerUriTemplate'>;

@@ -29,5 +28,7 @@ export { NativeCurrency } from '@safe-global/safe-gateway-typescript-sdk';

version?: string;
chainId?: BigNumberish;
chainId?: string | number | bigint | {
toNumber: () => number;
};
verifyingContract?: string;
salt?: BytesLike;
salt?: string;
}

@@ -45,2 +46,3 @@ export interface TypedDataTypes {

message: Record<string, any>;
primaryType?: string;
};

@@ -47,0 +49,0 @@ export type SignTypedMessageParams = {

{
"name": "@safe-global/safe-apps-sdk",
"version": "7.11.0",
"version": "8.0.0",
"description": "SDK developed to integrate third-party apps with Safe app.",

@@ -20,3 +20,3 @@ "main": "dist/src/index.js",

"test": "jest",
"format-dist": "sed -i '' 's/\"files\":/\"_files\":/' dist/package.json",
"format-dist": "sed -i 's/\"files\":/\"_files\":/' dist/package.json",
"build": "yarn rimraf dist && tsc && yarn format-dist"

@@ -28,3 +28,3 @@ },

"@safe-global/safe-gateway-typescript-sdk": "^3.5.3",
"ethers": "^5.7.2"
"viem": "^1.0.0"
},

@@ -31,0 +31,0 @@ "devDependencies": {

@@ -0,0 +0,0 @@ # Safe Apps SDK

@@ -0,0 +0,0 @@ import { SDKMessageEvent } from './../types/messaging';

@@ -0,0 +0,0 @@ import { MessageFormatter } from './messageFormatter';

@@ -0,0 +0,0 @@ import { ErrorResponse, SDKRequestData, RequestId, SuccessResponse, MethodToResponse } from '../types';

@@ -0,0 +0,0 @@ export enum Methods {

@@ -0,0 +0,0 @@ // i.e. 0-255 -> '00'-'ff'

@@ -0,0 +0,0 @@ import { Methods } from '../communication';

@@ -0,0 +0,0 @@ export const RPC_CALLS = {

@@ -0,0 +0,0 @@ import SDK from '../index';

@@ -0,0 +0,0 @@ import { RPC_CALLS } from '../eth/constants';

@@ -0,0 +0,0 @@ import SDK from './sdk';

@@ -1,3 +0,3 @@

import { ethers } from 'ethers';
import { EIP_1271_INTERFACE, EIP_1271_BYTES_INTERFACE, MAGIC_VALUE_BYTES, MAGIC_VALUE } from './signatures';
import { encodeFunctionData, Address, hashMessage, hashTypedData } from 'viem';
import { MAGIC_VALUE_BYTES, MAGIC_VALUE } from './signatures';
import { Methods } from '../communication/methods';

@@ -60,6 +60,31 @@ import { RPC_CALLS } from '../eth/constants';

const encodedIsValidSignatureCall = EIP_1271_INTERFACE.encodeFunctionData('isValidSignature', [
messageHash,
signature,
]);
const encodedIsValidSignatureCall = encodeFunctionData({
abi: [
{
constant: false,
inputs: [
{
name: '_dataHash',
type: 'bytes32',
},
{
name: '_signature',
type: 'bytes',
},
],
name: 'isValidSignature',
outputs: [
{
name: '',
type: 'bytes4',
},
],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
},
] as const,
functionName: 'isValidSignature',
args: [messageHash as Address, signature as Address],
});

@@ -90,8 +115,32 @@ const payload = {

const safeInfo = await this.getInfo();
const msgBytes = ethers.utils.arrayify(messageHash);
const encodedIsValidSignatureCall = EIP_1271_BYTES_INTERFACE.encodeFunctionData('isValidSignature', [
msgBytes,
signature,
]);
const encodedIsValidSignatureCall = encodeFunctionData({
abi: [
{
constant: false,
inputs: [
{
name: '_data',
type: 'bytes',
},
{
name: '_signature',
type: 'bytes',
},
],
name: 'isValidSignature',
outputs: [
{
name: '',
type: 'bytes4',
},
],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
},
] as const,
functionName: 'isValidSignature',
args: [messageHash as Address, signature as Address],
});

@@ -122,7 +171,33 @@ const payload = {

calculateMessageHash(message: string): string {
return ethers.utils.hashMessage(message);
return hashMessage(message);
}
calculateTypedMessageHash(typedMessage: EIP712TypedData): string {
return ethers.utils._TypedDataEncoder.hash(typedMessage.domain, typedMessage.types, typedMessage.message);
const chainId =
typeof typedMessage.domain.chainId === 'object'
? typedMessage.domain.chainId.toNumber()
: Number(typedMessage.domain.chainId);
let primaryType = typedMessage.primaryType;
if (!primaryType) {
const fields = Object.values(typedMessage.types);
// We try to infer primaryType (simplified ether's version)
const primaryTypes = Object.keys(typedMessage.types).filter((typeName) =>
fields.every((dataTypes) => dataTypes.every(({ type }) => type.replace('[', '').replace(']', '') !== typeName)),
);
if (primaryTypes.length === 0 || primaryTypes.length > 1) throw new Error('Please specify primaryType');
primaryType = primaryTypes[0];
}
return hashTypedData({
message: typedMessage.message,
domain: {
...typedMessage.domain,
chainId,
verifyingContract: typedMessage.domain.verifyingContract as Address,
salt: typedMessage.domain.salt as Address,
},
types: typedMessage.types,
primaryType,
});
}

@@ -129,0 +204,0 @@

@@ -56,2 +56,53 @@ import SDK from '../sdk';

describe('SDK.safe.calculateTypedMessageHash', () => {
test('Should generate correct EIP-712 message hash', () => {
const safeInfoSpy = jest.spyOn(sdkInstance.safe, 'getInfo');
safeInfoSpy.mockImplementationOnce(
(): Promise<SafeInfo> =>
Promise.resolve({
chainId: 4,
safeAddress: '0x9C6FEA0B2eAc5b6D8bBB6C30401D42aA95398190',
owners: [],
threshold: 1,
isReadOnly: false,
}),
);
const typedMessage = {
domain: {
name: 'Ether Mail',
version: '1',
chainId: 1,
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
},
types: {
Person: [
{ name: 'name', type: 'string' },
{ name: 'wallet', type: 'address' },
],
Mail: [
{ name: 'from', type: 'Person' },
{ name: 'to', type: 'Person' },
{ name: 'contents', type: 'string' },
],
},
message: {
from: {
name: 'Cow',
wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
},
to: {
name: 'Bob',
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
},
contents: 'Hello, Bob!',
},
};
const expectedHash = '0xbe609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2';
const hash = sdkInstance.safe.calculateTypedMessageHash(typedMessage);
expect(hash).toEqual(expectedHash);
});
});
describe('SDK.safe.check1271Signature', () => {

@@ -70,3 +121,3 @@ test('Should send a valid message to the interface', async () => {

);
const message = '0x617070726f76652072756770756c6c0000000000000000000000000000000000'; // ethers.utils.formatBytes32String('approve rugpull')
const message = '0x617070726f76652072756770756c6c0000000000000000000000000000000000'; // stringToHex('approve rugpull', { size: 32 })
// @ts-expect-error method is private but we are testing it

@@ -115,3 +166,3 @@ sdkInstance.safe.check1271Signature(message);

const message = '0x617070726f76652072756770756c6c0000000000000000000000000000000000'; // ethers.utils.formatBytes32String('approve rugpull')
const message = '0x617070726f76652072756770756c6c0000000000000000000000000000000000'; // stringToHex('approve rugpull', { size: 32 })
// @ts-expect-error method is private but we are testing it

@@ -137,3 +188,3 @@ expect(await sdkInstance.safe.check1271Signature(message)).toEqual(true);

const message = '0x68616c6c6f000000000000000000000000000000000000000000000000000000'; // ethers.utils.formatBytes32String('hallo')
const message = '0x68616c6c6f000000000000000000000000000000000000000000000000000000'; // stringToHex('hallo')
// @ts-expect-error method is private but we are testing it

@@ -157,3 +208,3 @@ expect(await sdkInstance.safe.check1271Signature(message)).toEqual(false);

);
const message = '0x617070726f76652072756770756c6c0000000000000000000000000000000000'; // ethers.utils.formatBytes32String('approve rugpull')
const message = '0x617070726f76652072756770756c6c0000000000000000000000000000000000'; // stringToHex('approve rugpull', { size: 32 })
// @ts-expect-error method is private but we are testing it

@@ -202,3 +253,3 @@ sdkInstance.safe.check1271SignatureBytes(message);

const message = '0x617070726f76652072756770756c6c0000000000000000000000000000000000'; // ethers.utils.formatBytes32String('approve rugpull')
const message = '0x617070726f76652072756770756c6c0000000000000000000000000000000000'; // stringToHex('approve rugpull', { size: 32 })
// @ts-expect-error method is private but we are testing it

@@ -224,3 +275,3 @@ expect(await sdkInstance.safe.check1271SignatureBytes(message)).toEqual(true);

const message = '0x68616c6c6f000000000000000000000000000000000000000000000000000000'; // ethers.utils.formatBytes32String('hallo')
const message = '0x68616c6c6f000000000000000000000000000000000000000000000000000000'; // stringToHex('hallo')
// @ts-expect-error method is private but we are testing it

@@ -235,3 +286,3 @@ expect(await sdkInstance.safe.check1271SignatureBytes(message)).toEqual(false);

// ethers.utils.formatBytes32String('approve rugpull')
// stringToHex('approve rugpull', { size: 32 })
const message = '0x617070726f76652072756770756c6c0000000000000000000000000000000000';

@@ -259,3 +310,3 @@ const expectedHash = '0xaae9257b8ff1c926ac3cdf36923661de4e81bf934e38958beeede3519aa18b08';

const message = '0x617070726f76652072756770756c6c0000000000000000000000000000000000'; // ethers.utils.formatBytes32String('approve rugpull')
const message = '0x617070726f76652072756770756c6c0000000000000000000000000000000000'; // stringToHex('approve rugpull', { size: 32 })

@@ -300,3 +351,3 @@ sdkInstance.safe.isMessageHashSigned(message);

// ethers.utils.formatBytes32String('approve rugpull')
// stringToHex('approve rugpull', { size: 32 })
const message = sdkInstance.safe.calculateMessageHash(

@@ -331,3 +382,3 @@ '0x617070726f76652072756770756c6c0000000000000000000000000000000000',

// ethers.utils.formatBytes32String('approve rugpull')
// stringToHex('approve rugpull', { size: 32 })
const message = sdkInstance.safe.calculateMessageHash(

@@ -362,3 +413,3 @@ '0x617070726f76652072756770756c6c0000000000000000000000000000000000',

// ethers.utils.formatBytes32String('approve rugpull')
// stringToHex('approve rugpull', { size: 32 })
const message = sdkInstance.safe.calculateMessageHash(

@@ -365,0 +416,0 @@ '0x617070726f76652072756770756c6c0000000000000000000000000000000000',

@@ -1,13 +0,4 @@

import { ethers } from 'ethers';
const MAGIC_VALUE = '0x1626ba7e';
const MAGIC_VALUE_BYTES = '0x20c13b0b';
const EIP_1271_INTERFACE = new ethers.utils.Interface([
'function isValidSignature(bytes32 _dataHash, bytes calldata _signature) external view',
]);
const EIP_1271_BYTES_INTERFACE = new ethers.utils.Interface([
'function isValidSignature(bytes calldata _data, bytes calldata _signature) public view',
]);
export { EIP_1271_INTERFACE, EIP_1271_BYTES_INTERFACE, MAGIC_VALUE, MAGIC_VALUE_BYTES };
export { MAGIC_VALUE, MAGIC_VALUE_BYTES };

@@ -0,0 +0,0 @@ import SDK from './index';

@@ -0,0 +0,0 @@ import { Communicator } from './types';

@@ -0,0 +0,0 @@ import { Methods } from '../communication/methods';

@@ -0,0 +0,0 @@ import SDK, { SafeInfo } from '../index';

@@ -0,0 +0,0 @@ import { SafeBalanceResponse, TransactionDetails, TokenInfo } from '@safe-global/safe-gateway-typescript-sdk';

@@ -0,0 +0,0 @@ export * from './sdk';

@@ -0,0 +0,0 @@ import { Methods } from '../communication/methods';

@@ -0,0 +0,0 @@ export type Permission = {

@@ -0,0 +0,0 @@ import { RPC_CALLS } from '../eth/constants';

import { ChainInfo as _ChainInfo } from '@safe-global/safe-gateway-typescript-sdk';
import { BigNumberish, BytesLike } from 'ethers';

@@ -39,5 +38,5 @@ export type ChainInfo = Pick<

version?: string;
chainId?: BigNumberish;
chainId?: string | number | bigint | { toNumber: () => number };
verifyingContract?: string;
salt?: BytesLike;
salt?: string;
}

@@ -56,2 +55,3 @@

message: Record<string, any>;
primaryType?: string;
};

@@ -58,0 +58,0 @@

@@ -0,0 +0,0 @@ import { getSDKVersion } from './utils';

@@ -0,0 +0,0 @@ import pkg from '../package.json';

@@ -0,0 +0,0 @@ import { Methods, RestrictedMethods } from '../communication/methods';

@@ -0,0 +0,0 @@ import SDK from '../sdk';

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc