Skip to content

Commit a9c2051

Browse files
Aaron CookDiogo Soaresiamacook
authored
Add data decoder/master copy endpoint calls (#42)
* build: Add get master copies + decoded data Co-authored-by: Aaron Cook <iamacook@users.noreply.github.com> * chore: Clean-up types * fix: Remove unnecessary test * fix: Broken tests + bump version * fix: Remove frontend types from response * build: Add e2e tests * fix: Remove lint Co-authored-by: Diogo Soares <diogo.soares@gnosis.pm> Co-authored-by: Aaron Cook <iamacook@users.noreply.github.com>
1 parent c84f332 commit a9c2051

File tree

11 files changed

+149
-471
lines changed

11 files changed

+149
-471
lines changed

e2e/get-decoded-data.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { getDecodedData } from '../src'
2+
import config from './config'
3+
4+
describe('getDecodedData tests', () => {
5+
it('should post getDecodedData', async () => {
6+
const result = await getDecodedData(
7+
config.baseUrl,
8+
'4',
9+
'0x095ea7b3000000000000000000000000ae9844f89d98c150f5e61bfc676d68b4921559900000000000000000000000000000000000000000000000000001c6bf52634000',
10+
)
11+
12+
expect(result).toStrictEqual({
13+
method: 'approve',
14+
parameters: [
15+
{
16+
name: 'spender',
17+
type: 'address',
18+
value: '0xae9844F89D98c150F5e61bfC676D68b492155990',
19+
},
20+
{
21+
name: 'value',
22+
type: 'uint256',
23+
value: '500000000000000',
24+
},
25+
],
26+
})
27+
})
28+
})

e2e/get-master-copy.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { getMasterCopies } from '../src'
2+
import config from './config'
3+
4+
describe('get mastercopy tests', () => {
5+
it('should get master copy response', async () => {
6+
const masterCopies = await getMasterCopies(config.baseUrl, '4')
7+
8+
expect(Array.isArray(masterCopies)).toBe(true)
9+
10+
// version 1.1.1 should be present
11+
const lastVersionRinkeby = masterCopies.find((mastercopy) => mastercopy.version === '1.1.1')
12+
expect(lastVersionRinkeby).toBeDefined()
13+
expect(lastVersionRinkeby.address).toBe('0x34CfAC646f301356fAa8B21e94227e3583Fe3F5F')
14+
})
15+
})

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@gnosis.pm/safe-react-gateway-sdk",
3-
"version": "2.6.0",
3+
"version": "2.7.0",
44
"main": "dist/index.min.js",
55
"types": "dist/index.d.ts",
66
"files": [

src/endpoint.ts

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,18 @@
1-
import { fetchData, insertParams, stringifyQuery } from './utils'
2-
import { paths } from './types/api'
1+
import { fetchData, stringifyQuery } from './utils'
32

43
type Primitive = string | number | boolean | null
54

65
interface Params {
7-
path?: { [key: string]: Primitive }
86
query?: { [key: string]: Primitive }
97
body?: unknown
108
}
119

12-
export function callEndpoint<T extends keyof paths>(
13-
baseUrl: string,
14-
path: T,
15-
parameters?: paths[T]['get']['parameters'],
16-
rawUrl?: string,
17-
): Promise<paths[T]['get']['responses'][200]['schema']> {
18-
let url = rawUrl
19-
let body
20-
if (!url) {
21-
const params = parameters as Params
22-
const pathname = insertParams(path, params?.path)
23-
const search = stringifyQuery(params?.query)
24-
url = `${baseUrl}${pathname}${search}`
25-
body = params?.body
10+
export function callEndpoint<T>(url: string, params?: Params, rawUrl?: string): Promise<T> {
11+
if (rawUrl) {
12+
return fetchData(rawUrl)
2613
}
2714

28-
return fetchData(url, body)
15+
const search = stringifyQuery(params?.query)
16+
const endpoint = `${url}${search}`
17+
return fetchData(endpoint, params?.body)
2918
}

src/index.ts

Lines changed: 58 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import { callEndpoint } from './endpoint'
2-
import { operations } from './types/api'
3-
import { SafeTransactionEstimation, TransactionDetails, TransactionListPage } from './types/transactions'
2+
import {
3+
MultisigTransactionRequest,
4+
SafeTransactionEstimation,
5+
SafeTransactionEstimationRequest,
6+
TransactionDetails,
7+
TransactionListPage,
8+
} from './types/transactions'
49
import { FiatCurrencies, OwnedSafes, SafeBalanceResponse, SafeCollectibleResponse, SafeInfo } from './types/common'
10+
import { MasterCopyReponse } from './types/master-copies'
511
import { ChainListResponse, ChainInfo } from './types/chains'
612
import { SafeAppsResponse } from './types/safe-apps'
13+
import { DecodedDataResponse } from './types/decoded-data'
714
export * from './types/safe-apps'
815
export * from './types/transactions'
916
export * from './types/chains'
@@ -15,7 +22,7 @@ export * from './types/common'
1522
* Get basic information about a Safe. E.g. owners, modules, version etc
1623
*/
1724
export function getSafeInfo(baseUrl: string, chainId: string, address: string): Promise<SafeInfo> {
18-
return callEndpoint(baseUrl, '/chains/{chainId}/safes/{address}/', { path: { chainId, address } })
25+
return callEndpoint(`${baseUrl}/chains/${chainId}/safes/${address}/`)
1926
}
2027

2128
/**
@@ -26,10 +33,12 @@ export function getBalances(
2633
chainId: string,
2734
address: string,
2835
currency = 'usd',
29-
query: operations['safes_balances_list']['parameters']['query'] = {},
36+
query: {
37+
trusted?: boolean // Return trusted tokens
38+
exclude_spam?: boolean // Return spam tokens
39+
} = {},
3040
): Promise<SafeBalanceResponse> {
31-
return callEndpoint(baseUrl, '/chains/{chainId}/safes/{address}/balances/{currency}/', {
32-
path: { chainId, address, currency },
41+
return callEndpoint(`${baseUrl}/chains/${chainId}/safes/${address}/balances/${currency}/`, {
3342
query,
3443
})
3544
}
@@ -38,14 +47,14 @@ export function getBalances(
3847
* Get a list of supported fiat currencies (e.g. USD, EUR etc)
3948
*/
4049
export function getFiatCurrencies(baseUrl: string): Promise<FiatCurrencies> {
41-
return callEndpoint(baseUrl, '/balances/supported-fiat-codes')
50+
return callEndpoint(`${baseUrl}/balances/supported-fiat-codes`)
4251
}
4352

4453
/**
4554
* Get the addresses of all Safes belonging to an owner
4655
*/
4756
export function getOwnedSafes(baseUrl: string, chainId: string, address: string): Promise<OwnedSafes> {
48-
return callEndpoint(baseUrl, '/chains/{chainId}/owners/{address}/safes', { path: { chainId, address } })
57+
return callEndpoint(`${baseUrl}/chains/${chainId}/owners/${address}/safes`)
4958
}
5059

5160
/**
@@ -55,9 +64,12 @@ export function getCollectibles(
5564
baseUrl: string,
5665
chainId: string,
5766
address: string,
58-
query: operations['safes_collectibles_list']['parameters']['query'] = {},
67+
query: {
68+
trusted?: boolean // Return trusted tokens
69+
exclude_spam?: boolean // Return spam tokens
70+
} = {},
5971
): Promise<SafeCollectibleResponse[]> {
60-
return callEndpoint(baseUrl, '/chains/{chainId}/safes/{address}/collectibles/', { path: { chainId, address }, query })
72+
return callEndpoint(`${baseUrl}/chains/${chainId}/safes/${address}/collectibles/`, { query })
6173
}
6274

6375
/**
@@ -66,15 +78,10 @@ export function getCollectibles(
6678
export function getTransactionHistory(
6779
baseUrl: string,
6880
chainId: string,
69-
address: string,
81+
safeAddress: string,
7082
pageUrl?: string,
7183
): Promise<TransactionListPage> {
72-
return callEndpoint(
73-
baseUrl,
74-
'/chains/{chainId}/safes/{safe_address}/transactions/history',
75-
{ path: { chainId, safe_address: address }, query: {} },
76-
pageUrl,
77-
)
84+
return callEndpoint(`${baseUrl}/chains/${chainId}/safes/${safeAddress}/transactions/history`, undefined, pageUrl)
7885
}
7986

8087
/**
@@ -83,15 +90,10 @@ export function getTransactionHistory(
8390
export function getTransactionQueue(
8491
baseUrl: string,
8592
chainId: string,
86-
address: string,
93+
safeAddress: string,
8794
pageUrl?: string,
8895
): Promise<TransactionListPage> {
89-
return callEndpoint(
90-
baseUrl,
91-
'/chains/{chainId}/safes/{safe_address}/transactions/queued',
92-
{ path: { chainId, safe_address: address }, query: {} },
93-
pageUrl,
94-
)
96+
return callEndpoint(`${baseUrl}/chains/${chainId}/safes/${safeAddress}/transactions/queued`, undefined, pageUrl)
9597
}
9698

9799
/**
@@ -102,9 +104,7 @@ export function getTransactionDetails(
102104
chainId: string,
103105
transactionId: string,
104106
): Promise<TransactionDetails> {
105-
return callEndpoint(baseUrl, '/chains/{chainId}/transactions/{transactionId}', {
106-
path: { chainId, transactionId },
107-
})
107+
return callEndpoint(`${baseUrl}/chains/${chainId}/transactions/${transactionId}`)
108108
}
109109

110110
/**
@@ -113,11 +113,10 @@ export function getTransactionDetails(
113113
export function postSafeGasEstimation(
114114
baseUrl: string,
115115
chainId: string,
116-
address: string,
117-
body: operations['post_safe_gas_estimation']['parameters']['body'],
116+
safeAddress: string,
117+
body: SafeTransactionEstimationRequest,
118118
): Promise<SafeTransactionEstimation> {
119-
return callEndpoint(baseUrl, '/chains/{chainId}/safes/{safe_address}/multisig-transactions/estimations', {
120-
path: { chainId, safe_address: address },
119+
return callEndpoint(`${baseUrl}/chains/${chainId}/safes/${safeAddress}/multisig-transactions/estimations`, {
121120
body,
122121
})
123122
}
@@ -128,11 +127,10 @@ export function postSafeGasEstimation(
128127
export function proposeTransaction(
129128
baseUrl: string,
130129
chainId: string,
131-
address: string,
132-
body: operations['propose_transaction']['parameters']['body'],
130+
safeAddress: string,
131+
body: MultisigTransactionRequest,
133132
): Promise<TransactionDetails> {
134-
return callEndpoint(baseUrl, '/chains/{chainId}/transactions/{safe_address}/propose', {
135-
path: { chainId, safe_address: address },
133+
return callEndpoint(`${baseUrl}/chains/${chainId}/transactions/${safeAddress}/propose`, {
136134
body,
137135
})
138136
}
@@ -142,9 +140,13 @@ export function proposeTransaction(
142140
*/
143141
export function getChainsConfig(
144142
baseUrl: string,
145-
query?: operations['chains_list']['parameters']['query'],
143+
query?: {
144+
ordering?: string
145+
limit?: number
146+
offset?: number
147+
},
146148
): Promise<ChainListResponse> {
147-
return callEndpoint(baseUrl, '/chains/', {
149+
return callEndpoint(`${baseUrl}/chains/`, {
148150
query,
149151
})
150152
}
@@ -153,18 +155,31 @@ export function getChainsConfig(
153155
* Returns a chain config
154156
*/
155157
export function getChainConfig(baseUrl: string, chainId: string): Promise<ChainInfo> {
156-
return callEndpoint(baseUrl, '/chains/{chainId}/', {
157-
path: { chainId: chainId },
158-
})
158+
return callEndpoint(`${baseUrl}/chains/${chainId}/`)
159159
}
160160

161161
/**
162162
* Returns Safe Apps List
163163
*/
164164
export function getSafeApps(baseUrl: string, chainId: string): Promise<SafeAppsResponse> {
165-
return callEndpoint(baseUrl, '/chains/{chainId}/safe-apps', {
166-
path: { chainId: chainId },
167-
})
165+
return callEndpoint(`${baseUrl}/chains/${chainId}/safe-apps`)
168166
}
169167

168+
/**
169+
* Returns List of Master Copies
170+
*/
171+
export function getMasterCopies(baseUrl: string, chainId: string): Promise<MasterCopyReponse> {
172+
return callEndpoint(`${baseUrl}/chains/${chainId}/about/master-copies`)
173+
}
174+
175+
/**
176+
* Returns decoded data
177+
*/
178+
export function getDecodedData(baseUrl: string, chainId: string, encodedData: string): Promise<DecodedDataResponse> {
179+
return callEndpoint(`${baseUrl}/chains/${chainId}/data-decoder`, {
180+
body: {
181+
data: encodedData,
182+
},
183+
})
184+
}
170185
/* eslint-enable @typescript-eslint/explicit-module-boundary-types */

0 commit comments

Comments
 (0)