-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathactions.ts
140 lines (128 loc) · 3.36 KB
/
actions.ts
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import {
ActionAndData,
ActionChainContext,
ActionChainContextType,
ActionContextType,
ActionEncodeContext,
ActionKeyAndData,
ActionMap,
ActionOptions,
IChainContext,
UnifiedCosmosMsg,
} from '@dao-dao/types'
import { getAccountAddress } from './account'
/**
* Encode actions.
*/
export const encodeActions = async ({
actionMap,
encodeContext,
data,
options: { throwErrors = true } = {},
}: {
actionMap: ActionMap
encodeContext: ActionEncodeContext
data: ActionKeyAndData[]
options?: {
/**
* Whether or not to throw the error if a transform fails. If false, the
* error will be logged to the console, and the message will be skipped.
*
* Defaults to true.
*/
throwErrors?: boolean
}
}): Promise<UnifiedCosmosMsg[]> =>
(
await Promise.all(
data.map(async ({ actionKey, data }) => {
// If no action, skip it.
if (!actionKey) {
return []
}
// If no data, maybe throw error because this is invalidly selected.
if (!data) {
if (throwErrors) {
throw new Error('No action selected.')
}
return []
}
try {
const action = actionMap[actionKey]
if (!action) {
return []
}
await action.init()
return await action.encode(data, encodeContext)
} catch (err) {
if (throwErrors) {
throw err
}
console.error(err)
}
return []
})
)
).flat()
/**
* Resolve action keys with data to their actions.
*/
export const convertActionKeysAndDataToActions = (
actionMap: ActionMap,
actionKeysAndData: ActionKeyAndData[]
): ActionAndData[] =>
actionKeysAndData.flatMap(({ actionKey, data }) => {
const action = actionMap[actionKey]
return action
? {
action,
data,
}
: []
})
/**
* Get the address for the given action options for the given chain. If a DAO,
* this is the address of the native address on the same chain or the polytone
* proxy on that chain. For a wallet, this is the address registered in the
* wallet's profile, if any.
*/
export const getChainAddressForActionOptions = (
{ context, chain, address }: ActionOptions,
chainId: string
): string | undefined =>
// If on same chain, return address.
chain.chainId === chainId
? address
: // If on different chain, return DAO's polytone proxy address.
context.type === ActionContextType.Dao
? getAccountAddress({
accounts: context.dao.accounts,
chainId,
})
: // If on different chain, return wallet's chain profile address if set.
context.type === ActionContextType.Wallet
? context.profile?.chains[chainId]?.address
: undefined
/**
* Convert chain context to action chain context.
*/
export const convertChainContextToActionChainContext = (
chainContext: IChainContext
): ActionChainContext =>
chainContext.config
? {
type: ActionChainContextType.Supported,
...chainContext,
// Type-check.
config: chainContext.config,
}
: chainContext.base
? {
type: ActionChainContextType.Configured,
...chainContext,
config: chainContext.base,
}
: {
type: ActionChainContextType.Any,
...chainContext,
}