Skip to content

Commit 1986698

Browse files
committed
signhub: rewrite SignerStatus type
1 parent 906ef86 commit 1986698

File tree

3 files changed

+50
-57
lines changed

3 files changed

+50
-57
lines changed

packages/signhub/src/orchestrator.ts

+34-41
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,25 @@ export type Status = {
99
signers: { [signer: string]: SignerStatus }
1010
}
1111

12-
export type SignerStatusPending = {
13-
situation?: string
12+
export enum SignerState {
13+
INITIAL,
14+
SIGNING,
15+
SIGNED,
16+
ERROR
1417
}
1518

16-
export type SignerStatusRejected = {
17-
rejected: true
18-
error?: string
19-
}
20-
21-
export type SignerStatusSigned = {
22-
signature: ethers.BytesLike
23-
suffix: ethers.BytesLike
24-
}
25-
26-
export type SignerStatus = SignerStatusPending | SignerStatusRejected | SignerStatusSigned
27-
28-
export function isSignerStatusRejected(status: SignerStatus): status is SignerStatusRejected {
29-
return (status as SignerStatusRejected).rejected
30-
}
19+
export type SignerStatus =
20+
| { state: SignerState.INITIAL }
21+
| { state: SignerState.SIGNING; request: Promise<ethers.BytesLike> }
22+
| { state: SignerState.SIGNED; signature: ethers.BytesLike; suffix: ethers.BytesLike }
23+
| { state: SignerState.ERROR; error: any }
3124

32-
export function isSignerStatusSigned(status: SignerStatus): status is SignerStatusSigned {
33-
return (status as SignerStatusSigned).signature !== undefined
25+
export function isSignerStatusPending(
26+
status?: SignerStatus
27+
): status is undefined | { state: SignerState.INITIAL } | { state: SignerState.SIGNING; request: Promise<ethers.BytesLike> } {
28+
return status === undefined || status.state === SignerState.INITIAL || status.state === SignerState.SIGNING
3429
}
3530

36-
export function isSignerStatusPending(status: SignerStatus): status is SignerStatusPending {
37-
return !isSignerStatusRejected(status) && !isSignerStatusSigned(status)
38-
}
39-
40-
export const InitialSituation = 'Initial'
41-
4231
export interface SignatureOrchestrator {
4332
getSigners(): Promise<string[]>
4433

@@ -189,17 +178,22 @@ export class Orchestrator {
189178
const accepted = await Promise.allSettled(
190179
signers.map(async s => {
191180
const saddr = await s.getAddress()
192-
status.signers[saddr] = { situation: InitialSituation }
193-
try {
194-
const signature = await s.sign(message, metadata ?? {})
195-
const suffix = s.suffix()
196-
status.signers[saddr] = { signature, suffix }
197-
onStatusUpdate()
198-
return true
199-
} catch (error) {
200-
status.signers[saddr] = { rejected: true, error }
201-
onStatusUpdate()
202-
return false
181+
182+
status.signers[saddr] = {
183+
state: SignerState.SIGNING,
184+
request: s
185+
.sign(message, metadata ?? {})
186+
.then(signature => {
187+
const suffix = s.suffix()
188+
status.signers[saddr] = { state: SignerState.SIGNED, signature, suffix }
189+
onStatusUpdate()
190+
return signature
191+
})
192+
.catch(error => {
193+
status.signers[saddr] = { state: SignerState.ERROR, error }
194+
onStatusUpdate()
195+
throw error
196+
})
203197
}
204198
})
205199
)
@@ -211,11 +205,10 @@ export class Orchestrator {
211205
if (promise.status === 'rejected') {
212206
const address = await signer.getAddress()
213207
console.warn(`signer ${address} rejected the request: ${promise.reason}`)
214-
status.signers[address] = { rejected: true, error: `signer ${address} rejected the request: ${promise.reason}` }
215-
} else if (!promise.value) {
216-
const address = await signer.getAddress()
217-
console.warn(`signer ${address} rejected the request`)
218-
status.signers[address] = { rejected: true, error: `signer ${address} rejected the request` }
208+
status.signers[address] = {
209+
state: SignerState.ERROR,
210+
error: new Error(`signer ${address} rejected the request: ${promise.reason}`)
211+
}
219212
}
220213
}
221214

packages/signhub/tests/orchestrator.spec.ts

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as chai from 'chai'
22
import { ethers } from 'ethers'
33
import { commons } from '@0xsequence/core'
4-
import { isSignerStatusPending, isSignerStatusRejected, isSignerStatusSigned, Orchestrator, Status } from '../src'
4+
import { isSignerStatusPending, Orchestrator, SignerState, Status } from '../src'
55
import { SapientSigner } from '../src/signers'
66

77
const { expect } = chai
@@ -37,15 +37,15 @@ describe('Orchestrator', () => {
3737
expect(status.signers).to.have.property(signer.address)
3838
const signerStatus = status.signers[signer.address]
3939

40-
if (isSignerStatusRejected(signerStatus)) {
40+
if (signerStatus.state === SignerState.ERROR) {
4141
numErrors++
4242
}
4343

4444
if (isSignerStatusPending(signerStatus)) {
4545
numPending++
4646
}
4747

48-
if (isSignerStatusSigned(signerStatus)) {
48+
if (signerStatus.state === SignerState.SIGNED) {
4949
numSignatures++
5050
}
5151
}
@@ -140,41 +140,41 @@ describe('Orchestrator', () => {
140140
expect(status.signers).to.have.property(await signer.getAddress())
141141
const signerStatus = status.signers[await signer.getAddress()]
142142

143-
if (isSignerStatusRejected(signerStatus)) {
143+
if (signerStatus.state === SignerState.ERROR) {
144144
numErrors++
145145
}
146146

147147
if (isSignerStatusPending(signerStatus)) {
148148
numPending++
149149
}
150150

151-
if (isSignerStatusSigned(signerStatus)) {
151+
if (signerStatus.state === SignerState.SIGNED) {
152152
numSignatures++
153153
}
154154
}
155155

156156
callbackCallsA++
157157

158158
expect(numErrors).to.be.equal(1)
159-
expect(numSignatures).to.be.equal(Math.max(callbackCallsA, 3))
160-
expect(numPending).to.be.equal(Math.min(signers.length - callbackCallsA, 0))
159+
expect(numSignatures).to.be.equal(2)
160+
expect(numPending).to.be.equal(0)
161161
})
162162

163163
const signature = await orchestrator.signMessage({ message: '0x1234' })
164-
expect(Object.keys(signature.signers)).to.have.lengthOf(signers.length)
164+
expect(Object.keys(signature.signers)).to.have.lengthOf(2)
165165

166166
for (const signer of signers) {
167167
const address = await signer.getAddress()
168168
const status = signature.signers[address]
169169

170170
if (address === (await brokenSigner.getAddress())) {
171-
if (isSignerStatusRejected(status)) {
172-
expect(status.error).to.contain('This is a broken signer.')
171+
if (status.state === SignerState.ERROR) {
172+
expect(status.error.message).to.contain('This is a broken signer.')
173173
} else {
174174
expect.fail('Signer should be rejected')
175175
}
176176
} else {
177-
expect(isSignerStatusSigned(status)).to.be.true
177+
expect(status.state === SignerState.SIGNED).to.be.true
178178
}
179179
}
180180
})
@@ -223,13 +223,13 @@ describe('Orchestrator', () => {
223223
const status = signature.signers[address]
224224

225225
if (address === (await rejectSigner.getAddress())) {
226-
if (isSignerStatusRejected(status)) {
227-
expect(status.error).to.contain('This is a rejected signer.')
226+
if (status.state === SignerState.ERROR) {
227+
expect(status.error.message).to.contain('This is a rejected signer.')
228228
} else {
229229
expect.fail('Signer should be rejected')
230230
}
231231
} else {
232-
expect(isSignerStatusSigned(status)).to.be.true
232+
expect(status.state === SignerState.SIGNED).to.be.true
233233
}
234234
}
235235
})

packages/wallet/src/wallet.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ethers } from 'ethers'
22
import { commons, v1, v2 } from '@0xsequence/core'
3-
import { isSignerStatusSigned, SignatureOrchestrator, Status } from '@0xsequence/signhub'
3+
import { SignatureOrchestrator, SignerState, Status } from '@0xsequence/signhub'
44
import { Deferrable, subDigestOf } from '@0xsequence/utils'
55
import { FeeQuote, Relayer } from '@0xsequence/relayer'
66
import { walletContracts } from '@0xsequence/abi'
@@ -37,7 +37,7 @@ const statusToSignatureParts = (status: Status) => {
3737

3838
for (const signer of Object.keys(status.signers)) {
3939
const value = status.signers[signer]
40-
if (isSignerStatusSigned(value)) {
40+
if (value.state === SignerState.SIGNED) {
4141
const suffix = ethers.utils.arrayify(value.suffix)
4242
const suffixed = ethers.utils.solidityPack(['bytes', 'bytes'], [value.signature, suffix])
4343

0 commit comments

Comments
 (0)