-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
459 additions
and
18 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# BC-UR-Registry-Tron | ||
|
||
This repository is the Ton extension of [bc-ur-registry](https://github.com/KeystoneHQ/ur-registry) | ||
|
||
## Installing | ||
|
||
To install, run: | ||
|
||
```bash | ||
yarn add @keystonehq/bc-ur-registry-ton | ||
``` | ||
|
||
```bash | ||
npm install --save @keystonehq/bc-ur-registry-ton | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// @ts-nocheck | ||
|
||
import { TonSignRequest, DataType } from "../src"; | ||
import * as uuid from "uuid"; | ||
|
||
describe("ton-sign-request", () => { | ||
it("should generate ton-sign-request", () => { | ||
const tonData = Buffer.from( | ||
"te6cckEBAgEARwABHCmpoxdmOz6lAAAACAADAQBoQgArFnMvHAX9tOjTp4/RDd3vP2Bn8xG+U5MTuKRKUE1NoqHc1lAAAAAAAAAAAAAAAAAAAHBy4G8=", | ||
"base64" | ||
); | ||
|
||
const tronRequestId = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"; | ||
const idBuffer = uuid.parse(tronRequestId) as Uint8Array; | ||
|
||
const tonSignRequest = new TonSignRequest({ | ||
requestId: Buffer.from(idBuffer), | ||
signData: tonData, | ||
dataType: DataType.TRANSACTION, | ||
address: "UQC1IywyQwixSOU8pezOZDC9rv2xCV4CGJzOWH6RX8BTsGJx", | ||
origin: "TonKeeper", | ||
}); | ||
|
||
const cborHex = tonSignRequest.toCBOR().toString("hex"); | ||
console.log(cborHex.toString("hex")); | ||
|
||
expect(cborHex.toString("hex")).toBe( | ||
"a501d825509b1deb4d3b7d4bad9bdd2b0d7b3dcb6d025856b5ee9c7241010201004700011c29a9a317663b3ea500000008000301006842002b16732f1c05fdb4e8d3a78fd10dddef3f6067f311be539313b8a44a504d4da2a1dcd65000000000000000000000000000007072e06f0301057830555143314979777951776978534f553870657a4f5a4443397276327843563443474a7a4f574836525838425473474a780669546f6e4b6565706572" | ||
); | ||
|
||
const ur = tonSignRequest.toUREncoder(1000).nextPart(); | ||
|
||
expect(ur).toBe( | ||
"ur:ton-sign-request/onadtpdagdndcawmgtfrkigrpmndutdnbtkgfssbjnaohdhfrewynsjpfpadaoadaeflaeadcedtptotchiyfrfmonaeaeaeayaeaxadaeisfwaedncmjkdlceahzcqzvsteosmyttbtutwsfhhniowfbyrngumubwrooxgegdgtgtoeoyuotbgdaeaeaeaeaeaeaeaeaeaeaeaeaeaejojpvtjlaxadahksdygogyfxehgakkktkkgyktinksgugwgoetjoihkngwhtfyfxesjpkoeyksfxhfeefxflgekngwhgfdengmhdetfwghjkflgeksaminghjljtgrihihjoihjpmduydrch" | ||
); | ||
const tonSignRequestDecoded = TonSignRequest.fromCBOR( | ||
Buffer.from(cborHex, "hex") | ||
); | ||
expect(uuid.stringify(tonSignRequest.getRequestId())).toBe(tronRequestId); | ||
expect(tonSignRequest.getOrigin()).toBe("TonKeeper"); | ||
expect(tonSignRequestDecoded.getSignData().toString("base64")).toEqual( | ||
"te6cckEBAgEARwABHCmpoxdmOz6lAAAACAADAQBoQgArFnMvHAX9tOjTp4/RDd3vP2Bn8xG+U5MTuKRKUE1NoqHc1lAAAAAAAAAAAAAAAAAAAHBy4G8=" | ||
); | ||
expect(tonSignRequestDecoded.getDerivationPath()).toEqual(undefined); | ||
expect(tonSignRequestDecoded.getAddress()).toEqual( | ||
"UQC1IywyQwixSOU8pezOZDC9rv2xCV4CGJzOWH6RX8BTsGJx" | ||
); | ||
}); | ||
|
||
it("should construct an TonSignRequest object from string", () => { | ||
const tonData = Buffer.from( | ||
"te6cckEBAgEARwABHCmpoxdmOz6lAAAACAADAQBoQgArFnMvHAX9tOjTp4/RDd3vP2Bn8xG+U5MTuKRKUE1NoqHc1lAAAAAAAAAAAAAAAAAAAHBy4G8=", | ||
"base64" | ||
); | ||
const requestID = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"; | ||
|
||
const request = TonSignRequest.constructTonRequest( | ||
tonData, | ||
DataType.TRANSACTION, | ||
"UQC1IywyQwixSOU8pezOZDC9rv2xCV4CGJzOWH6RX8BTsGJx", | ||
requestID, | ||
"TonKeeper", | ||
undefined, | ||
undefined | ||
); | ||
const ur = request.toUREncoder(1000).nextPart(); | ||
expect(ur).toBe( | ||
"ur:ton-sign-request/onadtpdagdndcawmgtfrkigrpmndutdnbtkgfssbjnaohdhfrewynsjpfpadaoadaeflaeadcedtptotchiyfrfmonaeaeaeayaeaxadaeisfwaedncmjkdlceahzcqzvsteosmyttbtutwsfhhniowfbyrngumubwrooxgegdgtgtoeoyuotbgdaeaeaeaeaeaeaeaeaeaeaeaeaeaejojpvtjlaxadahksdygogyfxehgakkktkkgyktinksgugwgoetjoihkngwhtfyfxesjpkoeyksfxhfeefxflgekngwhgfdengmhdetfwghjkflgeksaminghjljtgrihihjoihjpmduydrch" | ||
); | ||
}); | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// @ts-nocheck | ||
|
||
import { TonSignature, TronSignature, URRegistryDecoder } from "../src"; | ||
import * as uuid from "uuid"; | ||
|
||
describe("tron-signature", () => { | ||
it("should generate tron-signature", () => { | ||
const signature = Buffer.from( | ||
"47b1f77b3e30cfbbfa41d795dd34475865240617dd1c5a7bad526f5fd89e52cd057c80b665cc2431efab53520e2b1b92a0425033baee915df858ca1c588b0a1800", | ||
"hex" | ||
); | ||
const requestId = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"; | ||
const idBuffer = uuid.parse(requestId) as Uint8Array; | ||
|
||
const tronSignature = new TonSignature( | ||
signature, | ||
Buffer.from(idBuffer), | ||
); | ||
|
||
const cborHex = tronSignature.toCBOR().toString("hex"); | ||
const ur = tronSignature.toUREncoder(1000).nextPart(); | ||
expect(ur).toBe( | ||
"ur:tron-signature/oeadtpdagdndcawmgtfrkigrpmndutdnbtkgfssbjnaohdfpflpaylkgfmdytkrkzsfptsmduteeflhdihdkamchutcehtkgpmgmjlhetpnngmsnahkelarpihsfdkehwspygugmbadncwmonbfwgdeordwymehlyahdsgcehdlubkcsaebbckfpwy" | ||
); | ||
const tronSignatureDecoded = TronSignature.fromCBOR( | ||
Buffer.from(cborHex, "hex") | ||
); | ||
expect(uuid.stringify(tronSignatureDecoded.getRequestId())).toBe( | ||
requestId | ||
); | ||
expect(tronSignatureDecoded.getSignature().toString("hex")).toEqual( | ||
"47b1f77b3e30cfbbfa41d795dd34475865240617dd1c5a7bad526f5fd89e52cd057c80b665cc2431efab53520e2b1b92a0425033baee915df858ca1c588b0a1800" | ||
); | ||
|
||
const urDecoder = new URRegistryDecoder(); | ||
urDecoder.receivePart('ur:tron-signature/oeadtpdagdndcawmgtfrkigrpmndutdnbtkgfssbjnaohdfpflpaylkgfmdytkrkzsfptsmduteeflhdihdkamchutcehtkgpmgmjlhetpnngmsnahkelarpihsfdkehwspygugmbadncwmonbfwgdeordwymehlyahdsgcehdlubkcsaebbckfpwy'); | ||
const decodeSig = TronSignature.fromCBOR(urDecoder.resultUR().cbor); | ||
expect(decodeSig.getSignature().toString('hex')).toEqual('47b1f77b3e30cfbbfa41d795dd34475865240617dd1c5a7bad526f5fd89e52cd057c80b665cc2431efab53520e2b1b92a0425033baee915df858ca1c588b0a1800'); | ||
expect(decodeSig.getRequestId().toString('hex')).toEqual('9b1deb4d3b7d4bad9bdd2b0d7b3dcb6d'); | ||
}); | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
presets: [ | ||
["@babel/preset-env", { targets: { node: "current" } }], | ||
"@babel/preset-typescript", | ||
], | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "@keystonehq/bc-ur-registry-ton", | ||
"version": "0.1.0", | ||
"description": "bc-ur-registry extension for Tron", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"directories": { | ||
"lib": "src", | ||
"test": "__tests__" | ||
}, | ||
"files": [ | ||
"dist" | ||
], | ||
"scripts": { | ||
"clean": "rm -rf ./dist", | ||
"start": "tsdx watch", | ||
"build": "tsdx build", | ||
"test": "jest --passWithNoTests" | ||
}, | ||
"author": "Sora Li<[email protected]>", | ||
"license": "ISC", | ||
"dependencies": { | ||
"@keystonehq/bc-ur-registry": "^0.5.4", | ||
"uuid": "^9.0.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/preset-typescript": "^7.15.0", | ||
"@types/uuid": "^9.0.0", | ||
"jest": "^27.5.1", | ||
"tsdx": "^0.14.1", | ||
"typescript": "^4.9.4" | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { RegistryType } from "@keystonehq/bc-ur-registry"; | ||
|
||
export const ExtendedRegistryTypes = { | ||
TRON_SIGN_REQUEST: new RegistryType("ton-sign-request", 7201), | ||
TRON_SIGNATURE: new RegistryType("ton-signature", 7202) | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
import { | ||
CryptoKeypath, | ||
extend, | ||
DataItem, | ||
PathComponent, | ||
RegistryItem, | ||
DataItemMap, | ||
} from "@keystonehq/bc-ur-registry"; | ||
import { ExtendedRegistryTypes } from "./RegistryType"; | ||
import { parse as uuidParse } from "uuid"; | ||
|
||
const { decodeToDataItem, RegistryTypes } = extend; | ||
|
||
enum Keys { | ||
requestId = 1, | ||
signData, | ||
dataType, | ||
derivationPath, | ||
address, | ||
origin, | ||
} | ||
|
||
type SignRequestProps = { | ||
requestId?: Buffer; | ||
signData: Buffer; | ||
dataType: DataType; | ||
derivationPath?: CryptoKeypath; | ||
address: String; | ||
origin?: string; | ||
}; | ||
|
||
export enum DataType { | ||
TRANSACTION = 1, | ||
SIGN_PROOF = 2, | ||
} | ||
|
||
export class TonSignRequest extends RegistryItem { | ||
private requestId?: Buffer; | ||
private signData: Buffer; | ||
private dataType: DataType; | ||
private derivationPath?: CryptoKeypath; | ||
private address: String; | ||
private origin?: string; | ||
|
||
getRegistryType = () => ExtendedRegistryTypes.TRON_SIGN_REQUEST; | ||
|
||
constructor(args: SignRequestProps) { | ||
super(); | ||
this.requestId = args.requestId; | ||
this.signData = args.signData; | ||
this.derivationPath = args.derivationPath; | ||
this.address = args.address; | ||
this.origin = args.origin; | ||
this.dataType = args.dataType; | ||
} | ||
|
||
public getRequestId = () => this.requestId; | ||
public getSignData = () => this.signData; | ||
public getDerivationPath = () => this.derivationPath?.getPath(); | ||
public getAddress = () => this.address; | ||
public getOrigin = () => this.origin; | ||
public getDataType = () => this.dataType; | ||
|
||
public toDataItem = () => { | ||
const map: DataItemMap = {}; | ||
map[Keys.signData] = this.signData; | ||
map[Keys.dataType] = this.dataType; | ||
|
||
if (this.derivationPath) { | ||
const derivationPath = this.derivationPath.toDataItem(); | ||
derivationPath.setTag(this.derivationPath.getRegistryType().getTag()); | ||
map[Keys.derivationPath] = derivationPath; | ||
} | ||
|
||
if (this.requestId) { | ||
map[Keys.requestId] = new DataItem( | ||
this.requestId, | ||
RegistryTypes.UUID.getTag() | ||
); | ||
} | ||
|
||
if (this.address) { | ||
map[Keys.address] = this.address; | ||
} | ||
|
||
if (this.origin) { | ||
map[Keys.origin] = this.origin; | ||
} | ||
|
||
return new DataItem(map); | ||
}; | ||
|
||
public static fromDataItem = (dataItem: DataItem) => { | ||
const map = dataItem.getData(); | ||
|
||
const requestId = map[Keys.requestId] | ||
? map[Keys.requestId].getData() | ||
: undefined; | ||
|
||
const derivationPath = map[Keys.derivationPath] | ||
? CryptoKeypath.fromDataItem(map[Keys.derivationPath]) | ||
: undefined; | ||
|
||
return new TonSignRequest({ | ||
requestId, | ||
signData: map[Keys.signData], | ||
dataType: map[Keys.dataType], | ||
derivationPath, | ||
address: map[Keys.address], | ||
origin: map[Keys.origin], | ||
}); | ||
}; | ||
|
||
public static fromCBOR = (_cborPayload: Buffer) => { | ||
const dataItem = decodeToDataItem(_cborPayload); | ||
return TonSignRequest.fromDataItem(dataItem); | ||
}; | ||
|
||
public static parsePath(path: string, xfp: string) { | ||
const paths = path.replace(/[m|M]\//, "").split("/"); | ||
const pathComponent = paths.map((path) => { | ||
const index = parseInt(path.replace("'", "")); | ||
let isHardened = false; | ||
if (path.endsWith("'")) { | ||
isHardened = true; | ||
} | ||
return new PathComponent({ index, hardened: isHardened }); | ||
}); | ||
return new CryptoKeypath(pathComponent, Buffer.from(xfp, "hex")); | ||
} | ||
|
||
public static constructTonRequest( | ||
signData: Buffer, | ||
dataType: DataType, | ||
address: String, | ||
uuidString?: string, | ||
origin?: string, | ||
xfp?: string, | ||
derivationHDPath?: string | ||
) { | ||
return new TonSignRequest({ | ||
requestId: uuidString | ||
? Buffer.from(uuidParse(uuidString) as Uint8Array) | ||
: undefined, | ||
signData, | ||
dataType, | ||
derivationPath: | ||
derivationHDPath && xfp | ||
? TonSignRequest.parsePath(derivationHDPath, xfp) | ||
: undefined, | ||
address, | ||
origin, | ||
}); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { | ||
extend, | ||
DataItem, | ||
RegistryItem, | ||
DataItemMap | ||
} from "@keystonehq/bc-ur-registry"; | ||
import { ExtendedRegistryTypes } from "./RegistryType"; | ||
|
||
const { RegistryTypes, decodeToDataItem } = extend; | ||
|
||
enum Keys { | ||
requestId = 1, | ||
signature, | ||
origin, | ||
} | ||
|
||
export class TonSignature extends RegistryItem { | ||
private requestId?: Buffer; | ||
private signature: Buffer; | ||
private origin?: string; | ||
|
||
getRegistryType = () => ExtendedRegistryTypes.TRON_SIGNATURE; | ||
|
||
constructor( | ||
signature: Buffer, | ||
requestId?: Buffer, | ||
origin?: string, | ||
) { | ||
super(); | ||
this.signature = signature; | ||
this.requestId = requestId; | ||
this.origin = origin; | ||
} | ||
|
||
public getRequestId = () => this.requestId; | ||
public getSignature = () => this.signature; | ||
public getOrigin = () => this.origin; | ||
|
||
public toDataItem = () => { | ||
const map: DataItemMap = {}; | ||
map[Keys.requestId] = new DataItem( | ||
this.requestId, | ||
RegistryTypes.UUID.getTag() | ||
); | ||
map[Keys.signature] = this.signature; | ||
map[Keys.origin] = this.origin; | ||
return new DataItem(map); | ||
}; | ||
|
||
public static fromDataItem = (dataItem: DataItem) => { | ||
const map = dataItem.getData(); | ||
const signature = map[Keys.signature]; | ||
const requestId = map[Keys.requestId].getData(); | ||
const origin = map[Keys.origin]; | ||
return new TonSignature(signature, requestId, origin); | ||
}; | ||
|
||
public static fromCBOR = (_cborPayload: Buffer) => { | ||
const dataItem = decodeToDataItem(_cborPayload); | ||
return TonSignature.fromDataItem(dataItem); | ||
}; | ||
} |
Oops, something went wrong.