Skip to content

Commit df798c9

Browse files
authored
Merge pull request #1240 from IntersectMBO/add-stake-signing-primitives
cardano-wasm: add stake-key witnessing (signWithStakeKey / alsoSignWithStakeKey)
2 parents 7f01b05 + ed0289f commit df798c9

11 files changed

Lines changed: 205 additions & 12 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
description: Added `signWithStakeKey` and `alsoSignWithStakeKey` to the `cardano-wasm`
2+
API (on `UnsignedTx` and `SignedTx`), allowing transactions to be witnessed with
3+
a stake key. This makes stake delegation and (de)registration transactions submittable,
4+
as they require a witness from the stake credential.
5+
kind:
6+
- feature
7+
pr: 1240
8+
project: cardano-wasm

cardano-wasm/cardano-wasm.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ executable cardano-wasi
8080
if arch(wasm32)
8181
ghc-options:
8282
-no-hs-main
83-
"-optl-Wl,--strip-all,--export=hs_init,--export=newTx,--export=newUpcomingEraTx,--export=addTxInput,--export=addSimpleTxOut,--export=appendCertificateToTx,--export=setFee,--export=estimateMinFee,--export=signWithPaymentKey,--export=alsoSignWithPaymentKey,--export=toCbor,--export=makeStakeAddressStakeDelegationCertificate,--export=makeStakeAddressStakeDelegationCertificateUpcomingEra,--export=makeStakeAddressRegistrationCertificate,--export=makeStakeAddressRegistrationCertificateUpcomingEra,--export=makeStakeAddressUnregistrationCertificate,--export=makeStakeAddressUnregistrationCertificateUpcomingEra,--export=generatePaymentWallet,--export=generateStakeWallet,--export=restorePaymentWalletFromSigningKeyBech32,--export=restoreStakeWalletFromSigningKeyBech32,--export=generateTestnetPaymentWallet,--export=generateTestnetStakeWallet,--export=restoreTestnetPaymentWalletFromSigningKeyBech32,--export=restoreTestnetStakeWalletFromSigningKeyBech32,--export=getAddressBech32,--export=getBech32ForPaymentVerificationKey,--export=getBech32ForPaymentSigningKey,--export=getBech32ForStakeVerificationKey,--export=getBech32ForStakeSigningKey,--export=getBase16ForPaymentVerificationKeyHash,--export=getBase16ForStakeVerificationKeyHash,--export=mallocNBytes,--export=getStrLen,--export=freeMemory"
83+
"-optl-Wl,--strip-all,--export=hs_init,--export=newTx,--export=newUpcomingEraTx,--export=addTxInput,--export=addSimpleTxOut,--export=appendCertificateToTx,--export=setFee,--export=estimateMinFee,--export=signWithPaymentKey,--export=signWithStakeKey,--export=alsoSignWithPaymentKey,--export=alsoSignWithStakeKey,--export=toCbor,--export=makeStakeAddressStakeDelegationCertificate,--export=makeStakeAddressStakeDelegationCertificateUpcomingEra,--export=makeStakeAddressRegistrationCertificate,--export=makeStakeAddressRegistrationCertificateUpcomingEra,--export=makeStakeAddressUnregistrationCertificate,--export=makeStakeAddressUnregistrationCertificateUpcomingEra,--export=generatePaymentWallet,--export=generateStakeWallet,--export=restorePaymentWalletFromSigningKeyBech32,--export=restoreStakeWalletFromSigningKeyBech32,--export=generateTestnetPaymentWallet,--export=generateTestnetStakeWallet,--export=restoreTestnetPaymentWalletFromSigningKeyBech32,--export=restoreTestnetStakeWalletFromSigningKeyBech32,--export=getAddressBech32,--export=getBech32ForPaymentVerificationKey,--export=getBech32ForPaymentSigningKey,--export=getBech32ForStakeVerificationKey,--export=getBech32ForStakeSigningKey,--export=getBase16ForPaymentVerificationKeyHash,--export=getBase16ForStakeVerificationKeyHash,--export=mallocNBytes,--export=getStrLen,--export=freeMemory"
8484
other-modules:
8585
Cardano.Wasi.Internal.Api.Certificate.StakeCertificate
8686
Cardano.Wasi.Internal.Api.GRPC

cardano-wasm/js-test/basic-test.golden

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
    setFee: function (lovelaceAmount)
1818
    estimateMinFee: function (protocolParams,numKeyWitnesses,numByronKeyWitnesses,totalRefScriptSize)
1919
    signWithPaymentKey: function (signingKey)
20+
    signWithStakeKey: function (signingKey)
2021
  }
2122
> "Estimated fee:"
2223
> 164005n
2324
> "SignedTx object:"
2425
> [object] {
2526
    objectType: SignedTx
2627
    alsoSignWithPaymentKey: function (signingKey)
28+
    alsoSignWithStakeKey: function (signingKey)
2729
    txToCbor: function ()
2830
  }
2931
> "Tx CBOR:"

cardano-wasm/lib-wrapper/signed-tx.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ declare interface SignedTx {
1818
*/
1919
alsoSignWithPaymentKey(signingKey: string): SignedTx;
2020

21+
/**
22+
* Adds an extra signature to the transaction with a stake key.
23+
* @param signingKey The signing key to witness the transaction.
24+
* @returns The `SignedTx` object with the additional signature.
25+
*/
26+
alsoSignWithStakeKey(signingKey: string): SignedTx;
27+
2128
/**
2229
* Converts the signed transaction to its CBOR representation.
2330
* @returns A promise that resolves to the CBOR representation of the transaction as a hex string.

cardano-wasm/lib-wrapper/unsigned-tx.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ declare interface UnsignedTx {
5959
* @returns A promise that resolves to a `SignedTx` object.
6060
*/
6161
signWithPaymentKey(signingKey: string): Promise<SignedTx>;
62+
63+
/**
64+
* Signs the transaction with a stake key.
65+
* @param signingKey The signing key to witness the transaction.
66+
* @returns A promise that resolves to a `SignedTx` object.
67+
*/
68+
signWithStakeKey(signingKey: string): Promise<SignedTx>;
6269
}
6370

6471
export default UnsignedTx;

cardano-wasm/npm-wrapper/api.test.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,78 @@ describe('Cardano API', () => {
4646
expect(txCbor).toBe("84a300d9010281825820be6efd42a3d7b9a00d09d77a5d41e55ceaf0bd093a8aa8a893ce70d9caafd97800018182581d6082935e44937e8b530f32ce672b5d600d0a286b4e8a52c6555f659b871a0098968002192710a100d9010281825820adfc1c30385916da87db1ba3328f0690a57ebb2a6ac9f6f86b2d97f943adae0058400b19a00593e659ad0f10951f0f7d1e8a8b93112c60f67277529f91340581639e92ed4d0042ff92a0076cd69deb7e708acfdb73bb4ae79cf4bc06fd6d15efa208f5f6");
4747
});
4848

49+
// Delegation requires a witness from the stake credential, added with the stake key.
50+
it('should build a delegation transaction signed with a payment key and a stake key', async () => {
51+
// Test constants
52+
const PREVIEW_MAGIC_NUMBER = 2;
53+
const paymentSecretKey = "addr_sk1648253w4tf6fv5fk28dc7crsjsaw7d9ymhztd4favg3cwkhz7x8sl5u3ms";
54+
const stakeSecretKey = "stake_sk10pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rc0puqawrffl";
55+
const poolId = "b".repeat(56);
56+
const txInputHash = "be6efd42a3d7b9a00d09d77a5d41e55ceaf0bd093a8aa8a893ce70d9caafd978";
57+
const outputAddress = "addr_test1vzpfxhjyjdlgk5c0xt8xw26avqxs52rtf69993j4tajehpcue4v2v";
58+
59+
// Restore a stake wallet (holds both a payment and a stake key)
60+
const wallet = await api.wallet.testnet.restoreStakeWalletFromSigningKeyBech32(
61+
PREVIEW_MAGIC_NUMBER, paymentSecretKey, stakeSecretKey);
62+
const stakeKeyHash = await wallet.getBase16ForStakeVerificationKeyHash();
63+
64+
// Delegate the stake credential to a pool
65+
const delegationCert = await api.certificate.mainnetEra
66+
.makeStakeAddressStakeDelegationCertificate(stakeKeyHash, poolId);
67+
68+
// Build a transaction that includes the delegation certificate
69+
const tx = (await api.tx.newTx())
70+
.addTxInput(txInputHash, 0)
71+
.addSimpleTxOut(outputAddress, 5_000_000n)
72+
.appendCertificateToTx(delegationCert)
73+
.setFee(10_000n);
74+
75+
// Sign with the payment key, then add a witness from the stake key
76+
const signedTx = (await tx.signWithPaymentKey(paymentSecretKey))
77+
.alsoSignWithStakeKey(stakeSecretKey);
78+
expect(signedTx).toBeDefined();
79+
80+
const txCbor = await signedTx.txToCbor();
81+
82+
expect(txCbor).toBe("84a400d9010281825820be6efd42a3d7b9a00d09d77a5d41e55ceaf0bd093a8aa8a893ce70d9caafd97800018182581d6082935e44937e8b530f32ce672b5d600d0a286b4e8a52c6555f659b871a004c4b400219271004d901028183028200581ca9461e687627cddc5f54ffc988bc44321189538c601f1ad1b7979d9b581cbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba100d9010282825820adfc1c30385916da87db1ba3328f0690a57ebb2a6ac9f6f86b2d97f943adae005840b5df44de4b1302d1b031363cfb9636be2f395561dcf083d1192656677506bfa401d988d745f2ee2d11ed9e563f35cc2dfbb605c7cd58a613e42377e5e2a8da01825820ee31f83c88a71219a6fcf9bee0da9bc22620588f5a15a6145553504df9649e5c58402a2a37f2391bdf3a1ff52a7ed2103473f35b43022ed101bddcb18a557f7e9f9eac75c3562b142cc15dc9ebd006da34f4076ff413914ec90e4359d757d73bfc06f5f6");
83+
});
84+
85+
// The stake key can also be the first signer, with the payment witness added afterwards.
86+
// Witnesses live in a set, so the resulting transaction is identical regardless of signing order.
87+
it('should build a delegation transaction signed with a stake key and then a payment key', async () => {
88+
// Test constants
89+
const PREVIEW_MAGIC_NUMBER = 2;
90+
const paymentSecretKey = "addr_sk1648253w4tf6fv5fk28dc7crsjsaw7d9ymhztd4favg3cwkhz7x8sl5u3ms";
91+
const stakeSecretKey = "stake_sk10pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rc0puqawrffl";
92+
const poolId = "b".repeat(56);
93+
const txInputHash = "be6efd42a3d7b9a00d09d77a5d41e55ceaf0bd093a8aa8a893ce70d9caafd978";
94+
const outputAddress = "addr_test1vzpfxhjyjdlgk5c0xt8xw26avqxs52rtf69993j4tajehpcue4v2v";
95+
96+
// Restore a stake wallet (holds both a payment and a stake key)
97+
const wallet = await api.wallet.testnet.restoreStakeWalletFromSigningKeyBech32(
98+
PREVIEW_MAGIC_NUMBER, paymentSecretKey, stakeSecretKey);
99+
const stakeKeyHash = await wallet.getBase16ForStakeVerificationKeyHash();
100+
101+
// Delegate the stake credential to a pool
102+
const delegationCert = await api.certificate.mainnetEra
103+
.makeStakeAddressStakeDelegationCertificate(stakeKeyHash, poolId);
104+
105+
// Build a transaction that includes the delegation certificate
106+
const tx = (await api.tx.newTx())
107+
.addTxInput(txInputHash, 0)
108+
.addSimpleTxOut(outputAddress, 5_000_000n)
109+
.appendCertificateToTx(delegationCert)
110+
.setFee(10_000n);
111+
112+
// Sign with the stake key first, then add a witness from the payment key
113+
const signedTx = (await tx.signWithStakeKey(stakeSecretKey))
114+
.alsoSignWithPaymentKey(paymentSecretKey);
115+
expect(signedTx).toBeDefined();
116+
117+
const txCbor = await signedTx.txToCbor();
118+
119+
// Identical to the payment-key-first delegation transaction above
120+
expect(txCbor).toBe("84a400d9010281825820be6efd42a3d7b9a00d09d77a5d41e55ceaf0bd093a8aa8a893ce70d9caafd97800018182581d6082935e44937e8b530f32ce672b5d600d0a286b4e8a52c6555f659b871a004c4b400219271004d901028183028200581ca9461e687627cddc5f54ffc988bc44321189538c601f1ad1b7979d9b581cbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba100d9010282825820adfc1c30385916da87db1ba3328f0690a57ebb2a6ac9f6f86b2d97f943adae005840b5df44de4b1302d1b031363cfb9636be2f395561dcf083d1192656677506bfa401d988d745f2ee2d11ed9e563f35cc2dfbb605c7cd58a613e42377e5e2a8da01825820ee31f83c88a71219a6fcf9bee0da9bc22620588f5a15a6145553504df9649e5c58402a2a37f2391bdf3a1ff52a7ed2103473f35b43022ed101bddcb18a557f7e9f9eac75c3562b142cc15dc9ebd006da34f4076ff413914ec90e4359d757d73bfc06f5f6");
121+
});
122+
49123
});

cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,15 @@ apiInfo =
365365
, methodReturnType = NewObject (virtualObjectName signedTxObj)
366366
, methodReturnDoc = "A promise that resolves to a `SignedTx` object."
367367
}
368+
, MethodInfoEntry $
369+
MethodInfo
370+
{ methodName = "signWithStakeKey"
371+
, methodSimpleName = Nothing
372+
, methodDoc = "Signs the transaction with a stake key."
373+
, methodParams = [ParamInfo "signingKey" TSString "The signing key to witness the transaction."]
374+
, methodReturnType = NewObject (virtualObjectName signedTxObj)
375+
, methodReturnDoc = "A promise that resolves to a `SignedTx` object."
376+
}
368377
]
369378
}
370379

@@ -382,6 +391,15 @@ apiInfo =
382391
, methodReturnType = Fluent
383392
, methodReturnDoc = "The `SignedTx` object with the additional signature."
384393
}
394+
, MethodInfoEntry $
395+
MethodInfo
396+
{ methodName = "alsoSignWithStakeKey"
397+
, methodSimpleName = Nothing
398+
, methodDoc = "Adds an extra signature to the transaction with a stake key."
399+
, methodParams = [ParamInfo "signingKey" TSString "The signing key to witness the transaction."]
400+
, methodReturnType = Fluent
401+
, methodReturnDoc = "The `SignedTx` object with the additional signature."
402+
}
385403
, MethodInfoEntry $
386404
MethodInfo
387405
{ methodName = "txToCbor"

cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ module Cardano.Wasm.Api.Tx
2020
, estimateMinFeeImpl
2121
, setFeeImpl
2222
, signWithPaymentKeyImpl
23+
, signWithStakeKeyImpl
2324
, alsoSignWithPaymentKeyImpl
25+
, alsoSignWithStakeKeyImpl
2426
, toCborImpl
2527
)
2628
where
@@ -149,12 +151,12 @@ setFeeImpl (UnsignedTxObject era (Exp.UnsignedTx tx)) fee =
149151
let tx' = tx & Ledger.bodyTxL . Ledger.feeTxBodyL .~ fee
150152
in UnsignedTxObject era $ Exp.UnsignedTx tx'
151153

152-
-- | Sign an unsigned transaction using a payment key.
153-
signWithPaymentKeyImpl
154-
:: UnsignedTxObject -> Api.SigningKey Api.PaymentKey -> SignedTxObject
155-
signWithPaymentKeyImpl (UnsignedTxObject era fullUnsignedTx@(Exp.UnsignedTx tx)) signingKey =
154+
-- | Sign an unsigned transaction using any witness signing key.
155+
signWithKeyImpl
156+
:: UnsignedTxObject -> Api.ShelleyWitnessSigningKey -> SignedTxObject
157+
signWithKeyImpl (UnsignedTxObject era fullUnsignedTx@(Exp.UnsignedTx tx)) witnessSigningKey =
156158
obtainCommonConstraints era $
157-
let witness = Exp.makeKeyWitness era fullUnsignedTx . Api.WitnessPaymentKey $ signingKey
159+
let witness = Exp.makeKeyWitness era fullUnsignedTx witnessSigningKey
158160
txWits =
159161
Ledger.mkBasicTxWits
160162
& Ledger.addrTxWitsL
@@ -167,6 +169,16 @@ signWithPaymentKeyImpl (UnsignedTxObject era fullUnsignedTx@(Exp.UnsignedTx tx))
167169
era
168170
(Exp.SignedTx txWithWits)
169171

172+
-- | Sign an unsigned transaction using a payment key.
173+
signWithPaymentKeyImpl
174+
:: UnsignedTxObject -> Api.SigningKey Api.PaymentKey -> SignedTxObject
175+
signWithPaymentKeyImpl unsignedTxObject = signWithKeyImpl unsignedTxObject . Api.WitnessPaymentKey
176+
177+
-- | Sign an unsigned transaction using a stake key.
178+
signWithStakeKeyImpl
179+
:: UnsignedTxObject -> Api.SigningKey Api.StakeKey -> SignedTxObject
180+
signWithStakeKeyImpl unsignedTxObject = signWithKeyImpl unsignedTxObject . Api.WitnessStakeKey
181+
170182
newtype ProtocolParamsJSON = ProtocolParamsJSON String
171183

172184
-- | Estimate min fees for an unsigned transaction object.
@@ -226,12 +238,12 @@ instance FromJSON SignedTxObject where
226238
return $
227239
SignedTxObject era decodedTx
228240

229-
-- | Add an extra signature to an already signed transaction using a payment key.
230-
alsoSignWithPaymentKeyImpl
231-
:: SignedTxObject -> Api.SigningKey Api.PaymentKey -> SignedTxObject
232-
alsoSignWithPaymentKeyImpl (SignedTxObject era (Exp.SignedTx tx)) signingKey =
241+
-- | Add an extra signature to an already signed transaction using any witness signing key.
242+
alsoSignWithKeyImpl
243+
:: SignedTxObject -> Api.ShelleyWitnessSigningKey -> SignedTxObject
244+
alsoSignWithKeyImpl (SignedTxObject era (Exp.SignedTx tx)) witnessSigningKey =
233245
obtainCommonConstraints era $
234-
let witness = Exp.makeKeyWitness era (Exp.UnsignedTx tx) . Api.WitnessPaymentKey $ signingKey
246+
let witness = Exp.makeKeyWitness era (Exp.UnsignedTx tx) witnessSigningKey
235247
txWits =
236248
Ledger.mkBasicTxWits
237249
& Ledger.addrTxWitsL
@@ -244,6 +256,16 @@ alsoSignWithPaymentKeyImpl (SignedTxObject era (Exp.SignedTx tx)) signingKey =
244256
era
245257
(Exp.SignedTx txWithWits)
246258

259+
-- | Add an extra signature to an already signed transaction using a payment key.
260+
alsoSignWithPaymentKeyImpl
261+
:: SignedTxObject -> Api.SigningKey Api.PaymentKey -> SignedTxObject
262+
alsoSignWithPaymentKeyImpl signedTxObject = alsoSignWithKeyImpl signedTxObject . Api.WitnessPaymentKey
263+
264+
-- | Add an extra signature to an already signed transaction using a stake key.
265+
alsoSignWithStakeKeyImpl
266+
:: SignedTxObject -> Api.SigningKey Api.StakeKey -> SignedTxObject
267+
alsoSignWithStakeKeyImpl signedTxObject = alsoSignWithKeyImpl signedTxObject . Api.WitnessStakeKey
268+
247269
-- | Convert a signed transaction object to a base16 encoded string of its CBOR representation.
248270
toCborImpl :: SignedTxObject -> String
249271
toCborImpl (SignedTxObject era signedTx) =

cardano-wasm/src-wasi/Cardano/Wasi/Internal/Api/Tx.hs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ module Cardano.Wasi.Internal.Api.Tx
99
, setFee
1010
, estimateMinFee
1111
, signWithPaymentKey
12+
, signWithStakeKey
1213
, alsoSignWithPaymentKey
14+
, alsoSignWithStakeKey
1315
, toCbor
1416
)
1517
where
@@ -59,6 +61,9 @@ foreign export ccall "estimateMinFee"
5961
foreign export ccall "signWithPaymentKey"
6062
signWithPaymentKey :: UnsignedTxObjectJSON -> CString -> IO SignedTxObjectJSON
6163

64+
foreign export ccall "signWithStakeKey"
65+
signWithStakeKey :: UnsignedTxObjectJSON -> CString -> IO SignedTxObjectJSON
66+
6267
#endif
6368

6469
type UnsignedTxObjectJSON = CString
@@ -125,13 +130,24 @@ signWithPaymentKey unsignedTxObject signingKeyBech32 =
125130
<*> stringToSigningKey signingKeyBech32
126131
)
127132

133+
signWithStakeKey :: UnsignedTxObjectJSON -> CString -> IO SignedTxObjectJSON
134+
signWithStakeKey unsignedTxObject signingKeyBech32 =
135+
toCJSON
136+
=<< ( signWithStakeKeyImpl
137+
<$> fromCJSON True "UnsignedTx" unsignedTxObject
138+
<*> stringToSigningKey signingKeyBech32
139+
)
140+
128141
-- * SignedTxObject
129142

130143
#if defined(wasm32_HOST_ARCH)
131144

132145
foreign export ccall "alsoSignWithPaymentKey"
133146
alsoSignWithPaymentKey :: SignedTxObjectJSON -> CString -> IO SignedTxObjectJSON
134147

148+
foreign export ccall "alsoSignWithStakeKey"
149+
alsoSignWithStakeKey :: SignedTxObjectJSON -> CString -> IO SignedTxObjectJSON
150+
135151
foreign export ccall "toCbor"
136152
toCbor :: SignedTxObjectJSON -> IO CString
137153

@@ -147,6 +163,14 @@ alsoSignWithPaymentKey signedTxObject signingKeyBech32 =
147163
<*> stringToSigningKey signingKeyBech32
148164
)
149165

166+
alsoSignWithStakeKey :: SignedTxObjectJSON -> CString -> IO SignedTxObjectJSON
167+
alsoSignWithStakeKey signedTxObject signingKeyBech32 =
168+
toCJSON
169+
=<< ( alsoSignWithStakeKeyImpl
170+
<$> fromCJSON True "SignedTx" signedTxObject
171+
<*> stringToSigningKey signingKeyBech32
172+
)
173+
150174
toCbor :: SignedTxObjectJSON -> IO CString
151175
toCbor signedTxObject =
152176
newCString . toCborImpl

cardano-wasm/src-wasi/Cardano/Wasi/Internal/Conversion.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE CPP #-}
2+
{-# LANGUAGE FlexibleContexts #-}
23

34
module Cardano.Wasi.Internal.Conversion
45
( toCJSON
@@ -55,7 +56,8 @@ txIdToString txIdCString = do
5556
txId <- peekCString txIdCString
5657
rightOrError $ Api.deserialiseFromRawBytesHex (fromString txId)
5758

58-
stringToSigningKey :: CString -> IO (Api.SigningKey Api.PaymentKey)
59+
stringToSigningKey
60+
:: Api.SerialiseAsBech32 (Api.SigningKey keyrole) => CString -> IO (Api.SigningKey keyrole)
5961
stringToSigningKey signingKeyCString = do
6062
string <- peekCString signingKeyCString
6163
rightOrError $ Api.deserialiseFromBech32 (Text.pack string)

0 commit comments

Comments
 (0)