Last active
August 7, 2024 16:58
-
-
Save olegpetroveth/30bd051e40bf8f557521a575ed55696e to your computer and use it in GitHub Desktop.
Ledger Protobuf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
syntax = "proto3"; | |
package ledger_swap; | |
enum ExtraDataParsingMode { | |
NATIVE = 0; | |
EVM_CALLDATA = 1; | |
OP_RETURN = 2; | |
} | |
message NewTransactionResponse { | |
string payin_address = 1; | |
string payin_extra_id = 2; | |
string refund_address = 3; | |
string refund_extra_id = 4; | |
string payout_address = 5; | |
string payout_extra_id = 6; | |
string currency_from = 7; | |
string currency_to = 8; | |
bytes amount_to_provider = 9; | |
bytes amount_to_wallet = 10; | |
string device_transaction_id = 11; | |
bytes device_transaction_id_ng = 12; | |
bytes payin_extra_data = 13; | |
} | |
// =:ETH.USDC-B48:0xFD74b46Fbf014342505628ed43820F03E995dC35:1335183482296:tr:0 | |
// 3D 3A 45 54 48 2E 55 53 44 43 2D 42 34 38 3A 30 78 46 44 37 34 62 34 36 46 62 66 30 31 34 33 34 32 35 30 35 36 32 38 65 64 34 33 38 32 30 46 30 33 45 39 39 35 64 43 33 35 3A 31 33 33 35 31 38 33 34 38 32 32 39 36 3A 74 72 3A 30 | |
// then add 0x01 for prefix | |
// 01 3D 3A 45 54 48 2E 55 53 44 43 2D 42 34 38 3A 30 78 46 44 37 34 62 34 36 46 62 66 30 31 34 33 34 32 35 30 35 36 32 38 65 64 34 33 38 32 30 46 30 33 45 39 39 35 64 43 33 35 3A 31 33 33 35 31 38 3A 34 38 32 32 39 36 3A 74 72 3A 30 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import path from "path"; | |
import type { LedgerMessageProtobuf } from "@thorswap/models"; | |
import * as jose from "jose"; | |
import * as protobuf from "protobufjs"; | |
import { ErrorCode, SwapKitError } from "@thorswap/api-error"; | |
import { logger } from "@thorswap/logger"; | |
import { env } from "./env.mjs"; | |
export const signLedgerMessage = async ( | |
message: LedgerMessageProtobuf, | |
): Promise<{ | |
payload: string; | |
signature: string; | |
}> => { | |
try { | |
const ecPrivateKey = await jose.importPKCS8(env.LEDGER_PRIVATE_KEY, "ES256"); | |
// generateKeyPair(); | |
// const keyPair = await _generateKeyPair(); | |
// await _printPrivateKeyPKCS8(keyPair.privateKey); | |
// await _printPublicKeySPKI(keyPair.publicKey); | |
// return; | |
if (!CryptoKey) { | |
throw new SwapKitError({ | |
code: ErrorCode.ledgerSignFailed, | |
args: ["Failed to import private key"], | |
}); | |
} | |
const root = await new protobuf.Root().load( | |
path.join(__dirname, "ledger_swap_response.proto"), | |
{ | |
keepCase: true, | |
}, | |
); | |
const protobufMessageType = root.lookupType("NewTransactionResponse"); | |
const errMsg = protobufMessageType.verify(message); | |
if (errMsg) { | |
throw new SwapKitError({ | |
code: ErrorCode.ledgerSignFailed, | |
args: [errMsg], | |
}); | |
} | |
const protoMessage = protobufMessageType.fromObject(message); | |
const byteArray = protobufMessageType.encode(protoMessage).finish(); | |
const buffer = Buffer.from(byteArray); | |
const payloadBase64 = buffer.toString("base64url"); | |
const jws = await new jose.FlattenedSign(new TextEncoder().encode(payloadBase64)) | |
.setProtectedHeader({ alg: "ES256" }) | |
.sign(ecPrivateKey); | |
return { | |
payload: payloadBase64, | |
signature: jws.signature, | |
}; | |
} catch (e) { | |
logger.error(e); | |
return { | |
payload: "", | |
signature: "", | |
}; | |
} | |
}; | |
// async function _generateKeyPair() { | |
// const { publicKey, privateKey } = await jose.generateKeyPair("ES256", { | |
// extractable: true, | |
// }); | |
// return { publicKey, privateKey }; | |
// } | |
// async function _printPrivateKeyPKCS8(privateKey: jose.KeyLike) { | |
// const pkcs8 = await jose.exportPKCS8(privateKey); | |
// console.log("PKCS8 Private Key:", pkcs8); | |
// } | |
// async function _printPublicKeySPKI(publicKey: jose.KeyLike) { | |
// const spki = await jose.exportSPKI(publicKey); | |
// console.log("SPKI Public Key:", spki); | |
// } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment