1
- import { boostCoreAbi , prepareBoostPayload } from '@boostxyz/evm' ;
2
- import type { Config } from '@wagmi/core' ;
1
+ import {
2
+ type BoostPayload ,
3
+ boostCoreAbi ,
4
+ prepareBoostPayload ,
5
+ } from '@boostxyz/evm' ;
6
+ import { type Config , getAccount } from '@wagmi/core' ;
3
7
import { createWriteContract } from '@wagmi/core/codegen' ;
4
- import type { Address } from 'viem' ;
8
+ import { type Address , zeroAddress , zeroHash } from 'viem' ;
5
9
import type { Action } from './Actions/Action' ;
6
10
import type { AllowList } from './AllowLists/AllowList' ;
7
11
import type { Budget } from './Budgets/Budget' ;
12
+ import type { Deployable } from './Deployable/Deployable' ;
8
13
import type { Incentive } from './Incentives/Incentive' ;
9
14
import type { Validator } from './Validators/Validator' ;
10
15
@@ -25,7 +30,18 @@ export interface CreateBoostPayload {
25
30
protocolFee ?: bigint ;
26
31
referralFee ?: bigint ;
27
32
maxParticipants ?: bigint ;
28
- owner : Address ;
33
+ owner ?: Address ;
34
+ }
35
+
36
+ // TODO RFC?
37
+ // As dependencies are deployed, the iterator yields with the deployable and the remaining number of steps. finally, it yields with the address of
38
+ export interface CreateBoostProgress {
39
+ remaining : number ;
40
+ deployed : Deployable ;
41
+ }
42
+
43
+ export interface CreateBoostCompletion {
44
+ address : Address ;
29
45
}
30
46
31
47
export class BoostClient {
@@ -37,8 +53,7 @@ export class BoostClient {
37
53
this . config = config ;
38
54
}
39
55
40
- // TODO don't use boost payload, instead accept nice interface with Budget, Validator instances, etc.
41
- public async createBoost ( {
56
+ public async * createBoost ( {
42
57
budget,
43
58
action,
44
59
validator,
@@ -47,42 +62,143 @@ export class BoostClient {
47
62
protocolFee = 0n ,
48
63
referralFee = 0n ,
49
64
maxParticipants = 0n ,
50
- owner,
51
- } : CreateBoostPayload ) {
65
+ owner = zeroAddress ,
66
+ } : CreateBoostPayload ) : AsyncGenerator <
67
+ CreateBoostProgress | CreateBoostCompletion ,
68
+ Address
69
+ > {
52
70
const boostFactory = createWriteContract ( {
53
71
abi : boostCoreAbi ,
54
72
functionName : 'createBoost' ,
55
73
address : this . address ,
56
74
} ) ;
57
75
58
- // if (!payload.budget) {
59
- // // create simple budget
60
- // }
76
+ if ( ! owner ) {
77
+ owner = getAccount ( this . config ) . address || zeroAddress ;
78
+ if ( owner === zeroAddress ) {
79
+ // throw? TODO
80
+ console . warn ( 'No owner supplied, falling back to zeroAddress' ) ;
81
+ }
82
+ }
83
+
84
+ // As we proceed, decrement total steps to indiciate progress to consumer
85
+ let remainingSteps = 4 + incentives . length ;
86
+
87
+ let budgetPayload : Pick < BoostPayload , 'budget' > = {
88
+ budget : budget . address || zeroAddress ,
89
+ } ;
61
90
62
- // if (!payload.action) {
63
- // // idk
64
- // }
91
+ if ( budget . address === zeroAddress ) {
92
+ budget = await this . deploy ( budget ) ;
93
+ budgetPayload . budget = budget . address || zeroAddress ;
94
+ // TODO validate and throw?
95
+ }
96
+ yield {
97
+ remaining : -- remainingSteps ,
98
+ deployed : budget ,
99
+ } ;
65
100
66
- // if (!payload.validator) {
67
- // //
68
- // }
101
+ let actionPayload : Pick < BoostPayload , 'action' > = {
102
+ action : {
103
+ isBase : false ,
104
+ instance : action . address || zeroAddress ,
105
+ parameters : action . buildParameters ( this . config ) . args . at ( 0 ) || zeroHash ,
106
+ } ,
107
+ } ;
108
+ if ( actionPayload . action . instance === zeroAddress ) {
109
+ action = await this . deploy ( action ) ;
110
+ actionPayload . action . instance = action . address || zeroAddress ;
111
+ // TODO validate and throw?
112
+ }
113
+ yield {
114
+ remaining : -- remainingSteps ,
115
+ deployed : action ,
116
+ } ;
69
117
70
- // if (!payload.allowList) {
71
- // }
118
+ let validatorPayload : Pick < BoostPayload , 'validator' > = {
119
+ validator : {
120
+ isBase : false ,
121
+ instance : validator . address || zeroAddress ,
122
+ parameters :
123
+ validator . buildParameters ( this . config ) . args . at ( 0 ) || zeroHash ,
124
+ } ,
125
+ } ;
126
+ if ( validatorPayload . validator . instance === zeroAddress ) {
127
+ validator = await this . deploy ( validator ) ;
128
+ validatorPayload . validator . instance = validator . address || zeroAddress ;
129
+ // TODO validate and throw?
130
+ }
131
+ yield {
132
+ remaining : -- remainingSteps ,
133
+ deployed : validator ,
134
+ } ;
72
135
73
- // if (!payload.incentives) {
74
- // }
136
+ let allowListPayload : Pick < BoostPayload , 'allowList' > = {
137
+ allowList : {
138
+ isBase : false ,
139
+ instance : allowList . address || zeroAddress ,
140
+ parameters :
141
+ allowList . buildParameters ( this . config ) . args . at ( 0 ) || zeroHash ,
142
+ } ,
143
+ } ;
144
+ if ( allowListPayload . allowList . instance === zeroAddress ) {
145
+ allowList = await this . deploy ( allowList ) ;
146
+ allowListPayload . allowList . instance = allowList . address || zeroAddress ;
147
+ // TODO validate and throw?
148
+ }
149
+ yield {
150
+ remaining : -- remainingSteps ,
151
+ deployed : allowList ,
152
+ } ;
75
153
76
- // if (!payload.owner) {
77
- // const owner = getAccount(this.config);
78
- // payload.owner = owner.address;
79
- // }
154
+ let incentivesPayload : Pick < BoostPayload , 'incentives' > = {
155
+ incentives : incentives . map ( ( incentive ) => ( {
156
+ isBase : false ,
157
+ instance : incentive . address || zeroAddress ,
158
+ parameters :
159
+ incentive . buildParameters ( this . config ) . args . at ( 0 ) || zeroHash ,
160
+ } ) ) ,
161
+ } ;
162
+ for ( let i = 0 ; i < incentives . length ; i ++ ) {
163
+ let incentive = incentives . at ( i ) ! ;
164
+ const incentiveTarget = incentivesPayload . incentives . at ( i ) ! ;
165
+
166
+ if ( incentiveTarget . instance === zeroAddress ) {
167
+ incentive = await this . deploy ( incentive ) ;
168
+ incentiveTarget . instance = incentive . address || zeroAddress ;
169
+ // TODO validate and throw?
170
+ }
171
+ yield {
172
+ remaining : -- remainingSteps ,
173
+ deployed : incentive ,
174
+ } ;
175
+ }
176
+
177
+ const boostPayload : BoostPayload = {
178
+ ...budgetPayload ,
179
+ ...actionPayload ,
180
+ ...validatorPayload ,
181
+ ...allowListPayload ,
182
+ ...incentivesPayload ,
183
+ protocolFee,
184
+ referralFee,
185
+ maxParticipants,
186
+ owner,
187
+ } ;
80
188
81
189
const boost = await boostFactory ( this . config , {
82
- //TODO resolve this
83
- args : [ prepareBoostPayload ( payload ) ] ,
190
+ args : [ prepareBoostPayload ( boostPayload ) ] ,
84
191
} ) ;
85
192
193
+ yield {
194
+ address : boost ,
195
+ } ;
196
+
86
197
return boost ;
87
198
}
199
+
200
+ public async deploy < T extends Deployable > ( deployable : T ) {
201
+ await deployable . deploy ( this . config ) ;
202
+ return deployable ;
203
+ }
88
204
}
0 commit comments