forked from onflow/fcl-js
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathresolve-signatures.js
91 lines (86 loc) · 2.67 KB
/
resolve-signatures.js
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
import {isTransaction} from "../interaction/interaction.js"
import {sansPrefix} from "@onflow/util-address"
import {
encodeTransactionPayload as encodeInsideMessage,
encodeTransactionEnvelope as encodeOutsideMessage,
} from "../encode/encode.js"
import {
createSignableVoucher,
findInsideSigners,
findOutsideSigners,
} from "./voucher.js"
export async function resolveSignatures(ix) {
if (isTransaction(ix)) {
try {
let insideSigners = findInsideSigners(ix)
const insidePayload = encodeInsideMessage(prepForEncoding(ix))
await Promise.all(insideSigners.map(fetchSignature(ix, insidePayload)))
let outsideSigners = findOutsideSigners(ix)
const outsidePayload = encodeOutsideMessage({
...prepForEncoding(ix),
payloadSigs: insideSigners.map(id => ({
address: ix.accounts[id].addr,
keyId: ix.accounts[id].keyId,
sig: ix.accounts[id].signature,
})),
})
await Promise.all(outsideSigners.map(fetchSignature(ix, outsidePayload)))
} catch (error) {
console.error("Signatures", error, {ix})
throw error
}
}
return ix
}
function fetchSignature(ix, payload) {
return async function innerFetchSignature(id) {
const acct = ix.accounts[id]
if (acct.signature != null) return
const {signature} = await acct.signingFunction(
buildSignable(acct, payload, ix)
)
// if (!acct.role.proposer) {
// ix.accounts[id].keyId = keyId
// }
ix.accounts[id].signature = signature
}
}
export function buildSignable(acct, message, ix) {
try {
return {
f_type: "Signable",
f_vsn: "1.0.1",
message,
addr: sansPrefix(acct.addr),
keyId: acct.keyId,
roles: acct.role,
cadence: ix.message.cadence,
args: ix.message.arguments.map(d => ix.arguments[d].asArgument),
data: {},
interaction: ix,
voucher: createSignableVoucher(ix),
}
} catch (error) {
console.error("buildSignable", error)
throw error
}
}
function prepForEncoding(ix) {
return {
cadence: ix.message.cadence,
refBlock: ix.message.refBlock || null,
computeLimit: ix.message.computeLimit,
arguments: ix.message.arguments.map(id => ix.arguments[id].asArgument),
proposalKey: {
address: sansPrefix(ix.accounts[ix.proposer].addr),
keyId: ix.accounts[ix.proposer].keyId,
sequenceNum: ix.accounts[ix.proposer].sequenceNum,
},
payer: sansPrefix(ix.accounts[ix.payer].addr),
authorizers: ix.authorizations
.map(cid => sansPrefix(ix.accounts[cid].addr))
.reduce((prev, current) => {
return prev.find(item => item === current) ? prev : [...prev, current]
}, []),
}
}