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

fix(api-kit): add missing properties to types #1100

Merged
merged 4 commits into from
Jan 22, 2025
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
8 changes: 8 additions & 0 deletions packages/api-kit/src/SafeApiKit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
* @throws "Not Found"
* @throws "Ensure this field has at least 1 hexadecimal chars (not counting 0x)."
*/
async decodeData(data: string, to?: string): Promise<any> {

Check warning on line 125 in packages/api-kit/src/SafeApiKit.ts

View workflow job for this annotation

GitHub Actions / eslint

Unexpected any. Specify a different type
if (data === '') {
throw new Error('Invalid data')
}
Expand Down Expand Up @@ -258,6 +258,14 @@
return sendRequest({
url: `${this.#txServiceBaseUrl}/v1/safes/${address}/`,
method: HttpMethod.Get
}).then((response: any) => {

Check warning on line 261 in packages/api-kit/src/SafeApiKit.ts

View workflow job for this annotation

GitHub Actions / eslint

Unexpected any. Specify a different type
// FIXME remove when the transaction service returns the singleton property instead of masterCopy
if (!response?.singleton) {
const { masterCopy, ...rest } = response
return { ...rest, singleton: masterCopy } as SafeInfoResponse
}

return response as SafeInfoResponse
})
}

Expand Down Expand Up @@ -339,7 +347,7 @@
const { address: delegator } = this.#getEip3770Address(delegatorAddress)
const signature = await signDelegate(signer, delegate, this.#chainId)

const body: any = {

Check warning on line 350 in packages/api-kit/src/SafeApiKit.ts

View workflow job for this annotation

GitHub Actions / eslint

Unexpected any. Specify a different type
safe: safeAddress ? this.#getEip3770Address(safeAddress).address : null,
delegate,
delegator,
Expand Down
48 changes: 20 additions & 28 deletions packages/api-kit/src/types/safeTransactionServiceTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,20 +134,6 @@ export type PendingTransactionsOptions = {

export type SafeMultisigTransactionListResponse = ListResponse<SafeMultisigTransactionResponse>

export type TransferResponse = {
readonly type?: string
readonly executionDate: string
readonly blockNumber: number
readonly transactionHash: string
readonly to: string
readonly value: string
readonly tokenId: string
readonly tokenAddress?: string
readonly from: string
}

export type TransferListResponse = ListResponse<TransferResponse>

export type SafeModuleTransaction = {
readonly created?: string
readonly executionDate: string
Expand All @@ -165,36 +151,42 @@ export type SafeModuleTransaction = {

export type SafeModuleTransactionListResponse = ListResponse<SafeModuleTransaction>

export type Erc20Info = {
readonly name: string
readonly symbol: string
readonly decimals: number
readonly logoUri: string
export type TransferResponse = {
readonly type: string
readonly executionDate: string
readonly blockNumber: number
readonly transactionHash: string
readonly to: string
readonly value?: string
readonly tokenId?: string
readonly tokenAddress?: string
readonly transferId: string
readonly tokenInfo?: TokenInfoResponse
readonly from: string
}

export type TransferListResponse = ListResponse<TransferResponse>

export type TokenInfoResponse = {
readonly type?: string
readonly type: string
readonly address: string
readonly name: string
readonly symbol: string
readonly decimals: number
readonly decimals?: number
readonly logoUri?: string
readonly trusted: boolean
}

export type TokenInfoListResponse = ListResponse<TokenInfoResponse>

export type TransferWithTokenInfoResponse = TransferResponse & {
readonly tokenInfo: TokenInfoResponse
}

export type SafeModuleTransactionWithTransfersResponse = SafeModuleTransaction & {
readonly txType?: 'MODULE_TRANSACTION'
readonly transfers: TransferWithTokenInfoResponse[]
readonly transfers: TransferResponse[]
}

export type SafeMultisigTransactionWithTransfersResponse = SafeMultisigTransactionResponse & {
readonly txType?: 'MULTISIG_TRANSACTION'
readonly transfers: TransferWithTokenInfoResponse[]
readonly transfers: TransferResponse[]
}

export type EthereumTxResponse = {
Expand All @@ -208,7 +200,7 @@ export type EthereumTxResponse = {

export type EthereumTxWithTransfersResponse = EthereumTxResponse & {
readonly txType?: 'ETHEREUM_TRANSACTION'
readonly transfers: TransferWithTokenInfoResponse[]
readonly transfers: TransferResponse[]
}

export type AllTransactionsOptions = {
Expand Down
3 changes: 2 additions & 1 deletion packages/api-kit/tests/e2e/addMessageSignature.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SafeApiKit from '@safe-global/api-kit/index'
import chai from 'chai'
import chaiAsPromised from 'chai-as-promised'
import { getKits } from '../utils/setupKits'
import { API_TESTING_SAFE } from '../helpers/safe'

chai.use(chaiAsPromised)

Expand All @@ -18,7 +19,7 @@ const PRIVATE_KEY_2 = '0xb88ad5789871315d0dab6fc5961d6714f24f35a6393f13a6f426dfe

let safeApiKit: SafeApiKit
let protocolKit: Safe
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address
const signerSafeAddress = '0xDa8dd250065F19f7A29564396D7F13230b9fC5A3'

const generateRandomUUID = (): string => {
Expand Down
13 changes: 7 additions & 6 deletions packages/api-kit/tests/e2e/addSafeDelegate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import chai from 'chai'
import chaiAsPromised from 'chai-as-promised'
import config from '../utils/config'
import { getApiKit } from '../utils/setupKits'
import { API_TESTING_SAFE } from '../helpers/safe'

chai.use(chaiAsPromised)

Expand Down Expand Up @@ -68,7 +69,7 @@ describe('addSafeDelegate', () => {
})

it('should fail if Safe address is not checksummed', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'.toLowerCase()
const safeAddress = API_TESTING_SAFE.address.toLowerCase()
const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B'
const delegateConfig: AddSafeDelegateProps = {
safeAddress,
Expand All @@ -83,7 +84,7 @@ describe('addSafeDelegate', () => {
})

it('should fail if Safe delegate address is not checksummed', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address
const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B'.toLowerCase()
const delegateConfig: AddSafeDelegateProps = {
safeAddress,
Expand All @@ -98,7 +99,7 @@ describe('addSafeDelegate', () => {
})

it('should fail if Safe delegator address is not checksummed', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address
const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B'
const delegatorAddressLowerCase = delegatorAddress.toLowerCase()
const delegateConfig: AddSafeDelegateProps = {
Expand Down Expand Up @@ -129,7 +130,7 @@ describe('addSafeDelegate', () => {
})

it('should fail if the signer is not an owner of the Safe', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address
const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B'
const nonOwnerSigner = createWalletClient({
chain: sepolia,
Expand All @@ -152,7 +153,7 @@ describe('addSafeDelegate', () => {
})

it('should add a new delegate', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address
const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B'
const delegateConfig: AddSafeDelegateProps = {
safeAddress,
Expand Down Expand Up @@ -201,7 +202,7 @@ describe('addSafeDelegate', () => {
})

it('should add a new delegate EIP-3770', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address
const eip3770SafeAddress = `${config.EIP_3770_PREFIX}:${safeAddress}`
const delegateAddress = '0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B'
const eip3770DelegateAddress = `${config.EIP_3770_PREFIX}:${delegateAddress}`
Expand Down
37 changes: 34 additions & 3 deletions packages/api-kit/tests/e2e/getIncomingTransactions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import chaiAsPromised from 'chai-as-promised'
import SafeApiKit from '@safe-global/api-kit/index'
import config from '../utils/config'
import { getApiKit } from '../utils/setupKits'
import { API_TESTING_SAFE } from '../helpers/safe'

chai.use(chaiAsPromised)

Expand All @@ -21,7 +22,7 @@ describe('getIncomingTransactions', () => {
})

it('should fail if Safe address is not checksummed', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'.toLowerCase()
const safeAddress = API_TESTING_SAFE.address.toLowerCase()
await chai
.expect(safeApiKit.getIncomingTransactions(safeAddress))
.to.be.rejectedWith('Checksum address validation failed')
Expand All @@ -35,23 +36,53 @@ describe('getIncomingTransactions', () => {
})

it('should return the list of incoming transactions', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' // Safe with incoming transactions
const safeAddress = API_TESTING_SAFE.address // Safe with incoming transactions
const transferListResponse = await safeApiKit.getIncomingTransactions(safeAddress)
chai.expect(transferListResponse.count).to.be.equal(6)
chai.expect(transferListResponse.results.length).to.be.equal(6)
transferListResponse.results.map((transaction) => {
chai.expect(transaction.to).to.be.equal(safeAddress)
chai.expect(transaction).to.have.property('from').to.be.a('string')
chai.expect(transaction).to.have.property('executionDate').to.be.a('string')
chai.expect(transaction).to.have.property('blockNumber').to.be.a('number')
chai.expect(transaction).to.have.property('transactionHash').to.be.a('string')
chai.expect(transaction).to.have.property('transferId').to.be.a('string')
if (transaction.type === 'ETHER_TRANSFER') {
chai.expect(transaction.value).to.not.be.null
chai.expect(transaction.tokenId).to.be.null
chai.expect(transaction.tokenAddress).to.be.null
chai.expect(transaction.tokenInfo).to.be.null
} else if (transaction.type === 'ERC20_TRANSFER') {
chai.expect(transaction.tokenId).to.not.be.null
chai.expect(transaction.tokenAddress).to.not.be.null
chai.expect(transaction.tokenInfo).to.not.be.null
}
})
})

it('should return the list of incoming transactions EIP-3770', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78' // Safe with incoming transactions
const safeAddress = API_TESTING_SAFE.address // Safe with incoming transactions
const eip3770SafeAddress = `${config.EIP_3770_PREFIX}:${safeAddress}`
const transferListResponse = await safeApiKit.getIncomingTransactions(eip3770SafeAddress)
chai.expect(transferListResponse.count).to.be.equal(6)
chai.expect(transferListResponse.results.length).to.be.equal(6)
transferListResponse.results.map((transaction) => {
chai.expect(transaction.to).to.be.equal(safeAddress)
chai.expect(transaction).to.have.property('from').to.be.a('string')
chai.expect(transaction).to.have.property('executionDate').to.be.a('string')
chai.expect(transaction).to.have.property('blockNumber').to.be.a('number')
chai.expect(transaction).to.have.property('transactionHash').to.be.a('string')
chai.expect(transaction).to.have.property('transferId').to.be.a('string')
if (transaction.type === 'ETHER_TRANSFER') {
chai.expect(transaction.value).to.not.be.null
chai.expect(transaction.tokenId).to.be.null
chai.expect(transaction.tokenAddress).to.be.null
chai.expect(transaction.tokenInfo).to.be.null
} else if (transaction.type === 'ERC20_TRANSFER') {
chai.expect(transaction.tokenId).to.not.be.null
chai.expect(transaction.tokenAddress).to.not.be.null
chai.expect(transaction.tokenInfo).to.not.be.null
}
})
})
})
3 changes: 2 additions & 1 deletion packages/api-kit/tests/e2e/getMessage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import SafeApiKit from '@safe-global/api-kit/index'
import chai from 'chai'
import chaiAsPromised from 'chai-as-promised'
import { getApiKit } from '../utils/setupKits'
import { API_TESTING_SAFE } from '../helpers/safe'

chai.use(chaiAsPromised)

let safeApiKit: SafeApiKit
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address

describe('getMessage', () => {
before(async () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/api-kit/tests/e2e/getMessages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import SafeApiKit from '@safe-global/api-kit/index'
import chai from 'chai'
import chaiAsPromised from 'chai-as-promised'
import { getApiKit } from '../utils/setupKits'
import { API_TESTING_SAFE } from '../helpers/safe'

chai.use(chaiAsPromised)

let safeApiKit: SafeApiKit
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address

describe('getMessages', () => {
before(async () => {
Expand Down
10 changes: 6 additions & 4 deletions packages/api-kit/tests/e2e/getNextNonce.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import chaiAsPromised from 'chai-as-promised'
import SafeApiKit from '@safe-global/api-kit/index'
import config from '../utils/config'
import { getApiKit } from '../utils/setupKits'
import { API_TESTING_SAFE } from '../helpers/safe'

chai.use(chaiAsPromised)

let safeApiKit: SafeApiKit
Expand All @@ -20,16 +22,16 @@ describe('getNextNonce', () => {
})

it('should return the next Safe nonce when there are pending transactions', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address
const nextNonce = await safeApiKit.getNextNonce(safeAddress)
chai.expect(nextNonce).to.be.equal(13)
chai.expect(nextNonce).to.be.equal(API_TESTING_SAFE.nonce + 2)
})

it('should return the next Safe nonce when there are pending transactions EIP-3770', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address
const eip3770SafeAddress = `${config.EIP_3770_PREFIX}:${safeAddress}`
const nextNonce = await safeApiKit.getNextNonce(eip3770SafeAddress)
chai.expect(nextNonce).to.be.equal(13)
chai.expect(nextNonce).to.be.equal(API_TESTING_SAFE.nonce + 2)
})

it('should return the next Safe nonce when there are no pending transactions', async () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/api-kit/tests/e2e/getSafeDelegates.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import chai from 'chai'
import chaiAsPromised from 'chai-as-promised'
import config from '../utils/config'
import { getApiKit } from '../utils/setupKits'
import { API_TESTING_SAFE } from '../helpers/safe'

chai.use(chaiAsPromised)

Expand All @@ -19,7 +20,7 @@ let signer: DeleteSafeDelegateProps['signer']
let delegatorAddress: Address

describe('getSafeDelegates', () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address

before(() => {
safeApiKit = getApiKit('https://safe-transaction-sepolia.staging.5afe.dev/api')
Expand Down Expand Up @@ -127,7 +128,6 @@ describe('getSafeDelegates', () => {
})

it('should return an array of delegates EIP-3770', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const eip3770SafeAddress = `${config.EIP_3770_PREFIX}:${safeAddress}`
const delegateConfig1: DeleteSafeDelegateProps = {
delegateAddress: `${config.EIP_3770_PREFIX}:0x9cCBDE03eDd71074ea9c49e413FA9CDfF16D263B`,
Expand Down
31 changes: 26 additions & 5 deletions packages/api-kit/tests/e2e/getSafeInfo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import chai from 'chai'
import chaiAsPromised from 'chai-as-promised'
import config from '../utils/config'
import { getApiKit } from '../utils/setupKits'
import { API_TESTING_SAFE } from '../helpers/safe'

chai.use(chaiAsPromised)

Expand All @@ -21,26 +22,46 @@ describe('getSafeInfo', () => {
})

it('should fail if Safe address is not checksummed', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'.toLowerCase()
const safeAddress = API_TESTING_SAFE.address.toLowerCase()
await chai
.expect(safeApiKit.getSafeInfo(safeAddress))
.to.be.rejectedWith('Checksum address validation failed')
})

it('should return the Safe info if the address is correct', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address
const safeInfoResponse = await safeApiKit.getSafeInfo(safeAddress)
chai.expect(safeInfoResponse.address).to.be.equal(safeAddress)
chai.expect(safeInfoResponse.nonce).to.be.a('number')
chai.expect(safeInfoResponse.threshold).to.be.a('number')
chai.expect(safeInfoResponse.threshold).to.be.equal(API_TESTING_SAFE.threshold)
chai.expect(safeInfoResponse).to.have.property('owners').to.be.an('array')
chai.expect(safeInfoResponse).to.have.property('modules').to.be.an('array')
chai.expect(safeInfoResponse.fallbackHandler).to.eq(API_TESTING_SAFE.fallbackHandler)
chai.expect(safeInfoResponse.guard).to.eq(API_TESTING_SAFE.guard)
chai.expect(safeInfoResponse.version).to.eq(API_TESTING_SAFE.version)
chai.expect(safeInfoResponse).to.have.property('singleton').to.eq(API_TESTING_SAFE.singleton)
// FIXME currently the service returns masterCopy and we replace it by singleton on SafeApiKit.
// To avoid the breaking change they will return both propertys for a while, when this happens we can remove the hack at SafApiKit.
// The test will fail at that moment.
chai.expect(safeInfoResponse).not.to.have.property('masterCopy')
})

it('should return the Safe info if EIP-3770 address is correct', async () => {
const safeAddress = '0xF8ef84392f7542576F6b9d1b140334144930Ac78'
const safeAddress = API_TESTING_SAFE.address
const eip3770SafeAddress = `${config.EIP_3770_PREFIX}:${safeAddress}`
const safeInfoResponse = await safeApiKit.getSafeInfo(eip3770SafeAddress)
chai.expect(safeInfoResponse.address).to.be.equal(safeAddress)
chai.expect(safeInfoResponse.nonce).to.be.a('number')
chai.expect(safeInfoResponse.threshold).to.be.a('number')
chai.expect(safeInfoResponse.threshold).to.be.equal(API_TESTING_SAFE.threshold)
chai.expect(safeInfoResponse).to.have.property('owners').to.be.an('array')
chai.expect(safeInfoResponse).to.have.property('modules').to.be.an('array')
chai.expect(safeInfoResponse.fallbackHandler).to.eq(API_TESTING_SAFE.fallbackHandler)
chai.expect(safeInfoResponse.guard).to.eq(API_TESTING_SAFE.guard)
chai.expect(safeInfoResponse.version).to.eq(API_TESTING_SAFE.version)
chai.expect(safeInfoResponse).to.have.property('singleton').to.eq(API_TESTING_SAFE.singleton)
// FIXME currently the service returns masterCopy and we replace it by singleton on SafeApiKit.
// To avoid the breaking change they will return both propertys for a while, when this happens we can remove the hack at SafApiKit.
// The test will fail at that moment.
chai.expect(safeInfoResponse).not.to.have.property('masterCopy')
})
})
Loading
Loading