Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
51 changes: 45 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,46 @@

[![npm](https://img.shields.io/npm/v/@gnosis.pm/safe-react-gateway-sdk?label=%40gnosis.pm%2Fsafe-react-gateway-sdk)](https://www.npmjs.com/package/@gnosis.pm/safe-react-gateway-sdk)

A TypeScript SDK for the [Safe Gateway](https://github.com/gnosis/safe-client-gateway)
A TypeScript SDK for the [Safe Client Gateway](https://github.com/gnosis/safe-client-gateway)

## Links
📖 [API reference](https://gnosis.github.io/safe-react-gateway-sdk/modules.html#getBalances)

- [Gateway API docs](https://gnosis.github.io/safe-client-gateway/docs/routes/index.html)
- [SDK typedoc](https://gnosis.github.io/safe-react-gateway-sdk/modules.html#getBalances)
## Usage policy

NB: Safe Client Gateway isn't meant for public use.
Please _do not_ use this SDK if you're building, e.g., a Safe App.

## Using the SDK

Install:

```shell
yarn add @gnosis.pm/safe-react-gateway-sdk
```

Import:

```ts
import { getChainsConfig, type ChainListResponse } from '@gnosis.pm/safe-react-gateway-sdk'
```

Use:

```ts
const chains = await getChainsConfig()
```

The SDK needs no initialization unless you want to override the base URL, which defaults to https://safe-client.gnosis.io.
You can set an alternative base URL like so:

```ts
import { setBaseUrl } from '@gnosis.pm/safe-react-gateway-sdk'

// Switch the SDK to dev mode
setBaseUrl('https://safe-client.staging.gnosisdev.com')
```

The full SDK reference can be found [here](https://gnosis.github.io/safe-react-gateway-sdk/modules.html#getBalances).

## Adding an endpoint

Expand All @@ -26,16 +60,21 @@ To add a new endpoint, follow the pattern set by the existing endpoints.

This command will run before every commit:

```
```shell
yarn eslint:fix
```

## Tests

To run the unit and e2e tests locally:

```
```shell
yarn test
```

N.B.: the e2e tests make actual API calls on staging.


## Gateway API docs

The TypeScript types in this SDK are based on [Rust types](https://gnosis.github.io/safe-client-gateway/docs/routes/index.html) from the Gateway API.
14 changes: 9 additions & 5 deletions e2e/get-chains-config.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { getChainsConfig, getChainConfig } from '../src'
import { getChainsConfig, getChainConfig, setBaseUrl } from '../src'
import config from './config'

const mainnetChainId = '1'
const rinkebyChainId = '4'
const polygonChainId = '137'

describe('getChainsConfig & getChainConfig tests', () => {
beforeAll(() => {
setBaseUrl(config.baseUrl)
})

describe('getChainsConfig tests', () => {
it('Returns all chains config', async () => {
const chainConfig = await getChainsConfig(config.baseUrl)
const chainConfig = await getChainsConfig()

expect(chainConfig.results).toBe
expect(chainConfig.results).toBeDefined()
Expand All @@ -29,7 +33,7 @@ describe('getChainsConfig & getChainConfig tests', () => {

describe('getChainConfig/{chainId} tests', () => {
it('Returns Mainnet config', async () => {
const mainnetConfig = await getChainConfig(config.baseUrl, mainnetChainId)
const mainnetConfig = await getChainConfig(mainnetChainId)

expect(mainnetConfig).toBeDefined()
expect(mainnetConfig.chainId).toBe(mainnetChainId)
Expand All @@ -52,7 +56,7 @@ describe('getChainsConfig & getChainConfig tests', () => {
})

it('Returns Rinkeby config', async () => {
const rinkebyConfig = await getChainConfig(config.baseUrl, rinkebyChainId)
const rinkebyConfig = await getChainConfig(rinkebyChainId)

expect(rinkebyConfig).toBeDefined()
expect(rinkebyConfig.chainId).toBe(rinkebyChainId)
Expand All @@ -70,7 +74,7 @@ describe('getChainsConfig & getChainConfig tests', () => {
})

it('Returns Polygon config', async () => {
const polygonConfig = await getChainConfig(config.baseUrl, polygonChainId)
const polygonConfig = await getChainConfig(polygonChainId)

expect(polygonConfig).toBeDefined()
expect(polygonConfig.chainId).toBe(polygonChainId)
Expand Down
7 changes: 5 additions & 2 deletions e2e/get-decoded-data.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { getDecodedData } from '../src'
import { getDecodedData, setBaseUrl } from '../src'
import config from './config'

describe('getDecodedData tests', () => {
beforeAll(() => {
setBaseUrl(config.baseUrl)
})

it('should post getDecodedData', async () => {
const result = await getDecodedData(
config.baseUrl,
'4',
'0x095ea7b3000000000000000000000000ae9844f89d98c150f5e61bfc676d68b4921559900000000000000000000000000000000000000000000000000001c6bf52634000',
)
Expand Down
8 changes: 6 additions & 2 deletions e2e/get-master-copy.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { getMasterCopies } from '../src'
import { getMasterCopies, setBaseUrl } from '../src'
import config from './config'

describe('get mastercopy tests', () => {
beforeAll(() => {
setBaseUrl(config.baseUrl)
})

it('should get master copy response', async () => {
const masterCopies = await getMasterCopies(config.baseUrl, '4')
const masterCopies = await getMasterCopies('4')

expect(Array.isArray(masterCopies)).toBe(true)

Expand Down
12 changes: 8 additions & 4 deletions e2e/get-owned-safes.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import { getOwnedSafes } from '../src'
import { getOwnedSafes, setBaseUrl } from '../src'
import config from './config'

describe('getOwnedSafes tests', () => {
beforeAll(() => {
setBaseUrl(config.baseUrl)
})

it('should get owned safes on rinkeby', async () => {
const data = await getOwnedSafes(config.baseUrl, '4', '0x661E1CF4aAAf6a95C89EA8c81D120E6c62adDFf9')
const data = await getOwnedSafes('4', '0x661E1CF4aAAf6a95C89EA8c81D120E6c62adDFf9')

expect(data.safes).toContain('0x9B5dc27B104356516B05b02F6166a54F6D74e40B')
expect(data.safes).toContain('0xb3b83bf204C458B461de9B0CD2739DB152b4fa5A')
})

it('should return an empty array if no owned safes', async () => {
const data = await getOwnedSafes(config.baseUrl, '1', '0x661E1CF4aAAf6a95C89EA8c81D120E6c62adDFf9')
const data = await getOwnedSafes('1', '0x661E1CF4aAAf6a95C89EA8c81D120E6c62adDFf9')
expect(data).toEqual({ safes: [] })
})

it('should throw for bad addresses', async () => {
const req = getOwnedSafes(config.baseUrl, '4', '0x661E1CF4aAAf6a95C89EA8c81D120E6c62adDfF9')
const req = getOwnedSafes('4', '0x661E1CF4aAAf6a95C89EA8c81D120E6c62adDfF9')
await expect(req).rejects.toThrow(/Checksum address validation failed/)
})
})
8 changes: 6 additions & 2 deletions e2e/get-safe-apps.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { getSafeApps } from '../src'
import { getSafeApps, setBaseUrl } from '../src'
import config from './config'

const rinkebyChainId = '4'

describe('getSafeApps tests', () => {
beforeAll(() => {
setBaseUrl(config.baseUrl)
})

it('Returns Safe Apps List', async () => {
const safeAppsList = await getSafeApps(config.baseUrl, rinkebyChainId)
const safeAppsList = await getSafeApps(rinkebyChainId)

expect(safeAppsList).toBeDefined()
expect(Array.isArray(safeAppsList)).toBe(true)
Expand Down
8 changes: 6 additions & 2 deletions e2e/post-safe-gas-estimation.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { postSafeGasEstimation } from '../src'
import { postSafeGasEstimation, setBaseUrl } from '../src'
import config from './config'

describe('postSafeGasEstimation tests', () => {
beforeAll(() => {
setBaseUrl(config.baseUrl)
})

it('should post a safe gas estimation', async () => {
const result = await postSafeGasEstimation(config.baseUrl, '4', '0x4f9BD57BCC68Bf7770429F137922B3afD23d83E7', {
const result = await postSafeGasEstimation('4', '0x4f9BD57BCC68Bf7770429F137922B3afD23d83E7', {
to: '0x4f9BD57BCC68Bf7770429F137922B3afD23d83E7',
value: '1',
data: '0x',
Expand Down
8 changes: 6 additions & 2 deletions e2e/propose-transaction.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { proposeTransaction } from '../src'
import { proposeTransaction, setBaseUrl } from '../src'
import config from './config'

describe('proposeTransaction tests', () => {
beforeAll(() => {
setBaseUrl(config.baseUrl)
})

// Skipping this test, see https://github.com/gnosis/safe-client-gateway/issues/745
it('should propose a transaction and fail', async () => {
const req = proposeTransaction(config.baseUrl, '4', '0x4f9BD57BCC68Bf7770429F137922B3afD23d83E7', {
const req = proposeTransaction('4', '0x4f9BD57BCC68Bf7770429F137922B3afD23d83E7', {
to: '0x49d4450977E2c95362C13D3a31a09311E0Ea26A6',
value: '0',
data: '0xe8dde2320000000000000000000000000000000000000000000000000000000000000000',
Expand Down
8 changes: 6 additions & 2 deletions e2e/safe-collectibles-list.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { getCollectibles } from '../src'
import { getCollectibles, setBaseUrl } from '../src'
import config from './config'

describe('getCollectibles tests', () => {
beforeAll(() => {
setBaseUrl(config.baseUrl)
})

it('should fetch collectibles', async () => {
const address = '0xb3b83bf204C458B461de9B0CD2739DB152b4fa5A'
const data = await getCollectibles(config.baseUrl, '4', address)
const data = await getCollectibles('4', address)

expect(data.length).toBeGreaterThanOrEqual(1)
expect(typeof data[1].address).toBe('string')
Expand Down
8 changes: 6 additions & 2 deletions e2e/safes-read.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { getSafeInfo } from '../src'
import { getSafeInfo, setBaseUrl } from '../src'
import config from './config'

describe('getSafeInfo tests', () => {
beforeAll(() => {
setBaseUrl(config.baseUrl)
})

it('should get safe info on rinkeby', async () => {
const address = '0x9B5dc27B104356516B05b02F6166a54F6D74e40B'
const data = await getSafeInfo(config.baseUrl, '4', address)
const data = await getSafeInfo('4', address)

expect(data.address.value).toBe(address)
expect(data.chainId).toBe('4')
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gnosis.pm/safe-react-gateway-sdk",
"version": "2.10.3",
"version": "3.0.0",
"main": "dist/index.min.js",
"types": "dist/index.d.ts",
"files": [
Expand Down
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const DEFAULT_BASE_URL = 'https://safe-client.gnosis.io'
Loading