-
Notifications
You must be signed in to change notification settings - Fork 172
Expand file tree
/
Copy pathsafe.ts
More file actions
120 lines (101 loc) · 2.79 KB
/
safe.ts
File metadata and controls
120 lines (101 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import { Hash } from 'viem'
import { Connector, CreateConnectorFn } from 'wagmi'
import { safe, walletConnect } from 'wagmi/connectors'
export const SAFE_ENDPOINT = 'https://safe-client.safe.global'
type ConnectorType<TConnector extends (...args: any) => CreateConnectorFn> = ReturnType<
ReturnType<TConnector>
> & {
emitter: any
uid: any
}
const checkIsWcConnector = (c: Connector | undefined): c is ConnectorType<typeof walletConnect> =>
c?.type === walletConnect.type
const checkIsSafeConnector = (c: Connector | undefined): c is ConnectorType<typeof safe> =>
c?.type === safe.type
export type SafeAppType = 'iframe' | 'walletconnect'
export type CheckIsSafeAppReturnType = false | SafeAppType
export const checkIsSafeApp = async (
connector: Connector | undefined,
): Promise<CheckIsSafeAppReturnType> => {
const isWcConnector = checkIsWcConnector(connector)
const isSafeConnector = checkIsSafeConnector(connector)
if (!isWcConnector && !isSafeConnector) return false
if (isSafeConnector) return 'iframe'
const connectorProvider = await connector.getProvider()
const { session } = connectorProvider
if (!session) return false
const { name, url } = session.peer.metadata
if (name.startsWith('Safe') && url === 'https://app.safe.global/') return 'walletconnect'
return false
}
type SafeTx = {
safeAddress: string
txId: string
executedAt: number | null
txStatus: string
txInfo: {
type: string
to: object
dataSize: string
value: string
methodName: string
isCancellation: boolean
}
txData: {
hexData: string
dataDecoded: object
to: object
value: string
operation: number
}
detailedExecutionInfo: {
type: string
submittedAt: number
nonce: number
safeTxGas: string
baseGas: string
gasPrice: string
gasToken: string
refundReceiver: object
safeTxHash: string
executor: object | null
signers: object[]
confirmationsRequired: number
confirmations: object[]
trusted: boolean
}
txHash: Hash | null
}
type SafeError = {
code: number
// JSON encoded string
message: string
}
type SafeResponse = SafeTx | SafeError
export const fetchTxFromSafeTxHash = async ({
chainId,
safeTxHash,
}: {
chainId: number
safeTxHash: Hash
}): Promise<{ transactionHash: Hash } | null> => {
const data: SafeResponse = await fetch(
`${SAFE_ENDPOINT}/v1/chains/${chainId}/transactions/${safeTxHash}`,
{
method: 'GET',
headers: {
accept: 'application/json',
},
},
).then((res) => res.json())
// error
if ('code' in data) {
console.error(JSON.parse(data.message))
return null
}
if (!data.txHash) return null
return {
transactionHash: data.txHash,
}
}
export const isInsideSafe = () => typeof window !== 'undefined' && window !== window.parent