Skip to content

Commit

Permalink
add support and tests for polygon signing
Browse files Browse the repository at this point in the history
  • Loading branch information
localhuman committed Dec 1, 2022
1 parent a3bfc45 commit 911516c
Show file tree
Hide file tree
Showing 11 changed files with 447 additions and 15 deletions.
22 changes: 22 additions & 0 deletions src/__tests__/blockchain_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@
"blockchain": "eth",
"hash": "abcd",
"precision": 18
},
"matic": {
"blockchain": "polygon",
"hash": "0000000000000000000000000000000000000000",
"precision": 18
},
"derc20": {
"blockchain": "polygon",
"hash": "fe4f5145f6e09952a5ba9e956ed0c25e3fa4c7f1",
"precision": 18
}
},
"marketData": {
Expand Down Expand Up @@ -109,6 +119,12 @@
"minTradeSize": 5,
"minTradeIncrement": 8,
"minTradeIncrementB": 5
},
"matic_derc20": {
"minTickSize": 2,
"minTradeSize": 5,
"minTradeIncrement": 8,
"minTradeIncrementB": 5
}
},
"payloadSigningKey": {
Expand All @@ -124,6 +140,12 @@
"address": "fa39fddde46cea3060b91f80abed8672f77c5bea",
"index": 0
},
"polygon": {
"privateKey": "ceb3ba316f7aa4a7745d5d16eb9ac0491601428b828f7a1c1080f985e749a419",
"publicKey": "04446e9cda311fa5c0916430a48a41b35cc7604f037b5f7eec036b07ec97b0ffbf2162278ec211f81a98147b08ee650e3d33748075d93fcfe58562e81b3f76efae",
"address": "fa39fddde46cea3060b91f80abed8672f77c5bea",
"index": 0
},
"neo": {
"privateKey": "be0b6d54594784f4cf7b06ae4ed20073798ad253f244bd34d03166bdbc9c7b74",
"publicKey": "0292cbf3790801cef47c5cdc9abf4b010ec50aad117f595350d77ecd385d286e63",
Expand Down
16 changes: 16 additions & 0 deletions src/__tests__/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@
"blockchain": "eth",
"hash": "aed88173df2578fad078c48a33f0040364989fa8",
"precision": 18
},
"matic": {
"blockchain": "polygon",
"hash": "0000000000000000000000000000000000000000",
"precision": 18
},
"derc20": {
"blockchain": "polygon",
"hash": "fe4f5145f6e09952a5ba9e956ed0c25e3fa4c7f1",
"precision": 18
}
},
"marketData": {
Expand Down Expand Up @@ -125,6 +135,12 @@
"publicKey": "04be641c583207c310739a23973fb7cb7336d2b835517ede791e9fa53fa5b0fc46390ebb4dab62e8b01352f37308dbff1512615856bffd3c752db95737d3bc93a4",
"address": "55D16CA38dFB219141Ab6617B2872B978aF84702"
},
"polygon": {
"index": 0,
"privateKey": "0b7561f1c775ef4715accd21aac8629bcda2e6eb4e434c0d55c917bd7c297ac6",
"publicKey": "04be641c583207c310739a23973fb7cb7336d2b835517ede791e9fa53fa5b0fc46390ebb4dab62e8b01352f37308dbff1512615856bffd3c752db95737d3bc93a4",
"address": "55D16CA38dFB219141Ab6617B2872B978aF84702"
},
"btc": {
"index": 0,
"privateKey": "3a36746814d81d30f8a5d66ca85657f5455a73e34cb085465279bc989a30b337",
Expand Down
24 changes: 24 additions & 0 deletions src/__tests__/signatureVectors.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,30 @@
"blockchainSignatures": {
"eth": "e0b4e31781887a3639f24a0dee44356118f9ccc65158e7e06ef90581c7833be620ac6c6ff8906d3d0f87563c442944140b0da5ffb60d2cbfc8017a58d969bfc401"
}
},
"e": {
"address": "FA39FDDDE46CEA3060B91F80ABED8672F77C5BEA",
"nonce": 5432876,
"timestamp": 1565323885016,
"signature": "30440220083a73aaaa2b69476c74b64e0f1a1bdc1f6e5d311472729712eba8b5f3343a0a02204dcd5a5aac2693865b140c041cf85d6bd079c9a4803fe83caa218bb09d13d2c2",
"raw": {
"polygon": "02FA39FDDDE46CEA3060B91F80ABED8672F77C5BEA00000000000007E506D00052E62CFA39FDDDE46CEA3060B91F80ABED8672F77C5BEA"
},
"blockchainSignatures": {
"polygon": "a970ccafe7b0c4f2ec60594008603c8aed5c942ac30525f28e9c6e41f1c5dfd3cf19e790317094af6557c438ef0d67424f704deba684fceb91e02b468ba4c71801"
}
},
"f": {
"address": "FA39FDDDE46CEA3060B91F80ABED8672F77C5BEA",
"nonce": 5432876,
"timestamp": 1565362799120,
"signature": "30440220083a73aaaa2b69476c74b64e0f1a1bdc1f6e5d311472729712eba8b5f3343a0a02204dcd5a5aac2693865b140c041cf85d6bd079c9a4803fe83caa218bb09d13d2c2",
"raw": {
"polygon": "03FA39FDDDE46CEA3060B91F80ABED8672F77C5BEA000100000000121278900052E62CFA39FDDDE46CEA3060B91F80ABED8672F77C5BEA"
},
"blockchainSignatures": {
"polygon": "aea25dfbd61a2e0013e06f728d49f9bda50a135db0e2df1bdaa8101e0bc5d698f276adafdfed4d743291a8d0b97003e531c642fbdab5a88995162752aae8c06301"
}
}
},
"messages": {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/testVectors.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,4 @@
}
}
}
]
]
6 changes: 0 additions & 6 deletions src/generateWallet/generateWallet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ test('generates deterministic BIP44 NEO keys', async () => {
}
})


test('generates deterministic BIP44 NEO3 keys', async () => {

for (const vector of testVectors) {
const masterSeed = Buffer.from(vector.masterSeed, 'hex')

Expand All @@ -46,10 +44,8 @@ test('generates deterministic BIP44 NEO3 keys', async () => {
expect(genWallet.index).toBe(wallet.index)
}
}

})


test('generates deterministic BIP44 BTC keys', async () => {
for (const vector of testVectors) {
const masterSeed = Buffer.from(vector.masterSeed, 'hex')
Expand Down Expand Up @@ -124,8 +120,6 @@ test('generates deterministic BIP44 bitcoincash keys', async () => {
}
})



test('generates deterministic payload signing key', async () => {
for (const vector of testVectors) {
const masterSeed = Buffer.from(vector.masterSeed, 'hex')
Expand Down
20 changes: 15 additions & 5 deletions src/generateWallet/generateWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,19 @@ export enum CoinType {

const NON_SEGWIT = [CoinType.BCH, CoinType.DOGE]


/**
* Creates a wallet for a given token via the
* [BIP-44 protocol]((https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki).
*
* Requires the user's master seed.
*/
export function generateWallet(masterSeed: Buffer, coinType: CoinType, index: number, net?: string, blockchain?: Blockchain): Wallet {
export function generateWallet(
masterSeed: Buffer,
coinType: CoinType,
index: number,
net?: string,
blockchain?: Blockchain
): Wallet {
const key = derivePath(masterSeed, bip44Purpose, coinType, 0, 0)
const derivedChainKey = deriveIndex(key, index)

Expand Down Expand Up @@ -182,9 +187,14 @@ export const getAddressFromScriptHash = (scriptHash: string, addressVersion: str
return base58.encode(Buffer.from(addressVersion + scriptHashReversed + shaChecksum, 'hex'))
}


// NOTE: We can split this out later when there are more wallets needs to be derived.
function generateWalletForCoinType(key: bip32.BIP32Interface, coinType: CoinType, index: number, net?: string, blockchain?: Blockchain): Wallet {
function generateWalletForCoinType(
key: bip32.BIP32Interface,
coinType: CoinType,
index: number,
net?: string,
blockchain?: Blockchain
): Wallet {
if (key.privateKey === undefined) {
throw new Error('private key not properly derived')
}
Expand All @@ -194,7 +204,7 @@ function generateWalletForCoinType(key: bip32.BIP32Interface, coinType: CoinType
const publicKey = neoGetPublicKeyFromPrivateKey(neoPrivKey)
const verifiedScript = getVerificationScriptFromPublicKey(publicKey, blockchain)
const scriptHash = reverseHex(hash160(verifiedScript))
const addressVersion = (blockchain && blockchain === Blockchain.NEO3) ? NEO3_ADDR_VERSION : ADDR_VERSION
const addressVersion = blockchain && blockchain === Blockchain.NEO3 ? NEO3_ADDR_VERSION : ADDR_VERSION
return {
address: getAddressFromScriptHash(scriptHash, addressVersion),
index,
Expand Down
84 changes: 81 additions & 3 deletions src/signPayload/signPayload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ import {
signETHBlockchainData
} from '../signETHBlockchainData'

import {
presignPolygonBlockchainData,
buildPolygonMovementSignatureData,
buildPolygonOrderSignatureData,
signPolygonBlockchainData
} from '../signPolygonBlockchainData'

import { signBTC, preSignBTC } from '../signBTCBlockchainData'

const curve = new EC('secp256k1')
Expand Down Expand Up @@ -183,7 +190,8 @@ export default function signPayload(
{
btc: config.wallets.btc,
eth: config.wallets.eth,
neo: config.wallets.neo
neo: config.wallets.neo,
polygon: config.wallets.polygon
},
config.assetData,
{ kind, payload }
Expand Down Expand Up @@ -306,6 +314,9 @@ function buildMovementSignatureData(apiKey: APIKey, config: PresignConfig, paylo
case 'eth':
const ethData = buildETHMovementSignatureData(apiKey.child_keys[BIP44.ETH].address, payloadAndKind)
return ethData
case 'polygon':
const polygonData = buildPolygonMovementSignatureData(apiKey.child_keys[BIP44.POLYGON]!.address, payloadAndKind)
return polygonData
case 'btc':
return ''
default:
Expand Down Expand Up @@ -345,6 +356,10 @@ export async function presignBlockchainData(
const ethData = buildETHMovementSignatureData(apiKey.child_keys[BIP44.ETH].address, payloadAndKind)
const ethSig = await presignETHBlockchainData(apiKey, config, ethData)
return [ethSig]
case 'polygon':
const polygonData = buildPolygonMovementSignatureData(apiKey.child_keys[BIP44.POLYGON]!.address, payloadAndKind)
const polygonSig = await presignPolygonBlockchainData(apiKey, config, polygonData)
return [polygonSig]
case 'btc':
return []
default:
Expand Down Expand Up @@ -373,7 +388,6 @@ export async function presignBlockchainData(
nonceTo: chainNoncePair.nonceTo,
publicKey: apiKey.child_keys[BIP44.NEO].public_key.toLowerCase()
}
break
case 'eth':
const ethData = buildETHOrderSignatureData(
apiKey.child_keys[BIP44.ETH].address,
Expand All @@ -388,7 +402,20 @@ export async function presignBlockchainData(
nonceTo: chainNoncePair.nonceTo,
publicKey: apiKey.child_keys[BIP44.ETH].public_key
}
break
case 'polygon':
const polygonData = buildPolygonOrderSignatureData(
apiKey.child_keys[BIP44.POLYGON]!.address,
payloadAndKind,
chainNoncePair,
orderData
)
const polygonSignature = await presignPolygonBlockchainData(apiKey, config, polygonData)
return {
...polygonSignature,
nonceFrom: chainNoncePair.nonceFrom,
nonceTo: chainNoncePair.nonceTo,
publicKey: apiKey.child_keys[BIP44.POLYGON]!.public_key
}
case 'btc':
return {
blockchain: 'BTC',
Expand Down Expand Up @@ -434,6 +461,9 @@ export function signBlockchainData(config: Config, payloadAndKind: PayloadAndKin
case 'eth':
const ethData = buildETHMovementSignatureData(config.wallets.eth.address, payloadAndKind)
return [signETHBlockchainData(config.wallets.eth.privateKey, ethData)]
case 'polygon':
const polygonData = buildPolygonMovementSignatureData(config.wallets.polygon.address, payloadAndKind)
return [signPolygonBlockchainData(config.wallets.polygon.privateKey, polygonData)]
case 'btc':
return []
}
Expand Down Expand Up @@ -543,6 +573,11 @@ export function addRawBlockchainOrderData(config: Config, payloadAndKind: Payloa
payload: payloadAndKind.payload,
raw: buildETHOrderSignatureData(config.wallets.eth.address, payloadAndKind, chainNoncePair, orderData)
}
case 'polygon':
return {
payload: payloadAndKind.payload,
raw: buildPolygonOrderSignatureData(config.wallets.polygon.address, payloadAndKind, chainNoncePair, orderData)
}
case 'btc':
return {
payload: payloadAndKind.payload,
Expand Down Expand Up @@ -588,6 +623,16 @@ export function addRawPresignBlockchainOrderData(
orderData
)
}
case 'polygon':
return {
payload: payloadAndKind.payload,
raw: buildPolygonOrderSignatureData(
apiKey.child_keys[BIP44.POLYGON]!.address,
payloadAndKind,
chainNoncePair,
orderData
)
}
case 'btc':
return {
payload: payloadAndKind.payload,
Expand Down Expand Up @@ -663,6 +708,12 @@ export function signTransactionDigestsForAddMovement(config: Config, payload: Ad
message: item.payload,
signature: signETHBlockchainData(config.wallets.eth.privateKey, item.digest).signature
}
case Blockchain.POLYGON:
return {
blockchain: item.blockchain,
message: item.payload,
signature: signPolygonBlockchainData(config.wallets.polygon.privateKey, item.digest).signature
}
case Blockchain.NEO:
return {
blockchain: item.blockchain,
Expand Down Expand Up @@ -710,6 +761,15 @@ export async function presignTransactionDigestsForAddMovement(
signature: sig.signature
})
break
case Blockchain.POLYGON:
sig = await presignPolygonBlockchainData(apiKey, config, item.payloadHash, false)
result.push({
blockchain: item.blockchain,
message: item.payload,
r: sig.r,
signature: sig.signature
})
break
case Blockchain.NEO:
sig = await presignNEOBlockchainData(apiKey, config, item.payload, item.payloadHashFunction)
result.push({
Expand Down Expand Up @@ -758,6 +818,15 @@ export async function presignTransactionDigestsForIterateTransaction(
signature: sig.signature
})
break
case Blockchain.POLYGON:
sig = await presignPolygonBlockchainData(apiKey, config, item.payloadHash, false)
result.push({
blockchain: item.blockchain,
payloadHash: item.payloadHash,
r: sig.r,
signature: sig.signature
})
break
case Blockchain.NEO:
sig = await presignNEOBlockchainData(apiKey, config, item.payload, item.payloadHashFunction)
result.push({
Expand Down Expand Up @@ -787,6 +856,9 @@ export function signStateList(config: Config, items: ClientSignedState[]): Clien
case 'eth':
item.signature = signETHBlockchainData(config.wallets.eth.privateKey, item.message).signature
return item
case 'polygon':
item.signature = signPolygonBlockchainData(config.wallets.polygon.privateKey, item.message).signature
return item
case 'btc':
item.signature = signBTC(config.wallets.btc.privateKey, item.message).signature
return item
Expand All @@ -811,6 +883,12 @@ export async function presignStateList(
item.r = neoSig.r
result.push(item)
break
case 'polygon':
const polygonSig = await presignPolygonBlockchainData(apiKey, config, item.message)
item.signature = polygonSig.signature
item.r = polygonSig.r
result.push(item)
break
case 'neo':
const ethSig = await presignNEOBlockchainData(apiKey, config, item.message, HASH_DOUBLESHA256)
item.signature = ethSig.signature
Expand Down
6 changes: 6 additions & 0 deletions src/signPolygonBlockchainData/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export {
signPolygonBlockchainData,
buildPolygonMovementSignatureData,
presignPolygonBlockchainData,
buildPolygonOrderSignatureData
} from './signPolygonBlockchainData'
Loading

0 comments on commit 911516c

Please sign in to comment.