From 2ac58fa36af917c5e721a2efdf69aa2d47c79474 Mon Sep 17 00:00:00 2001 From: Sebastien Guillemot Date: Sun, 8 Oct 2023 07:07:45 +0800 Subject: [PATCH] Dynamically import crypto-specific packages (#232) --- .../paima-sdk/paima-crypto/src/algorand.ts | 24 ++++++++++--------- .../paima-sdk/paima-crypto/src/cardano.ts | 4 +++- .../paima-sdk/paima-crypto/src/polkadot.ts | 6 +++-- .../paima-sdk/paima-providers/src/algorand.ts | 7 +++--- .../paima-sdk/paima-providers/src/polkadot.ts | 9 +++---- 5 files changed, 27 insertions(+), 23 deletions(-) diff --git a/packages/paima-sdk/paima-crypto/src/algorand.ts b/packages/paima-sdk/paima-crypto/src/algorand.ts index e05458ce1..cb523ad61 100644 --- a/packages/paima-sdk/paima-crypto/src/algorand.ts +++ b/packages/paima-sdk/paima-crypto/src/algorand.ts @@ -1,6 +1,4 @@ import type { SignedTransaction, Transaction, SuggestedParams } from 'algosdk'; -import algosdk from 'algosdk'; -import nacl from 'tweetnacl'; import { doLog, hexStringToUint8Array } from '@paima/utils'; import web3UtilsPkg from 'web3-utils'; import type { IVerify } from './IVerify'; @@ -17,19 +15,19 @@ export class AlgorandCrypto implements IVerify { ): Promise => { try { const sig = Buffer.from(hexStringToUint8Array(signature)); - const txn = this.buildAlgorandTransaction(userAddress, message); + const txn = await this.buildAlgorandTransaction(userAddress, message); const signedTx: SignedTransaction = { txn, sig, }; - return await Promise.resolve(this.verifySignedTransaction(signedTx)); + return await this.verifySignedTransaction(signedTx); } catch (err) { doLog(`[funnel] error verifying algorand signature: ${err}`); return await Promise.resolve(false); } }; - buildAlgorandTransaction = (userAddress: string, message: string): Transaction => { + buildAlgorandTransaction = async (userAddress: string, message: string): Promise => { const hexMessage = web3UtilsPkg.utf8ToHex(message).slice(2); const msgArray = hexStringToUint8Array(hexMessage); const SUGGESTED_PARAMS: SuggestedParams = { @@ -39,7 +37,8 @@ export class AlgorandCrypto implements IVerify { genesisID: 'mainnet-v1.0', genesisHash: 'wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=', }; - return algosdk.makePaymentTxnWithSuggestedParams( + const { makePaymentTxnWithSuggestedParams } = await import('algosdk'); + return makePaymentTxnWithSuggestedParams( userAddress, userAddress, 0, @@ -49,22 +48,25 @@ export class AlgorandCrypto implements IVerify { ); }; - verifySignedTransaction = (signedTransaction: SignedTransaction): boolean => { + verifySignedTransaction = async (signedTransaction: SignedTransaction): Promise => { if (signedTransaction.sig === undefined) return false; const pkBytes = signedTransaction.txn.from.publicKey; const signatureBytes = new Uint8Array(signedTransaction.sig); - const transactionBytes = algosdk.encodeObj(signedTransaction.txn.get_obj_for_encoding()); + const { encodeObj } = await import('algosdk'); + const transactionBytes = encodeObj(signedTransaction.txn.get_obj_for_encoding()); const messageBytes = new Uint8Array(transactionBytes.length + 2); messageBytes.set(Buffer.from('TX')); messageBytes.set(transactionBytes, 2); - return nacl.sign.detached.verify(messageBytes, signatureBytes, pkBytes); + const { sign } = await import('tweetnacl'); + return sign.detached.verify(messageBytes, signatureBytes, pkBytes); }; - decodeSignedTransaction = (signedTx: Uint8Array): SignedTransaction => { - return algosdk.decodeSignedTransaction(signedTx); + decodeSignedTransaction = async (signedTx: Uint8Array): Promise => { + const { decodeSignedTransaction } = await import('algosdk'); + return decodeSignedTransaction(signedTx); }; } diff --git a/packages/paima-sdk/paima-crypto/src/cardano.ts b/packages/paima-sdk/paima-crypto/src/cardano.ts index 1a670f0fd..e7470e46f 100644 --- a/packages/paima-sdk/paima-crypto/src/cardano.ts +++ b/packages/paima-sdk/paima-crypto/src/cardano.ts @@ -1,4 +1,3 @@ -import verifyCardanoDataSignature from '@cardano-foundation/cardano-verify-datasignature'; import { doLog } from '@paima/utils'; import type { IVerify } from './IVerify'; @@ -17,6 +16,9 @@ export class CardanoCrypto implements IVerify { if (!signature || !key || remainder.length > 0) { return false; } + const { default: verifyCardanoDataSignature } = await import( + '@cardano-foundation/cardano-verify-datasignature' + ); return verifyCardanoDataSignature(signature, key, message, userAddress); } catch (err) { doLog('[address-validator] error verifying cardano signature:', err); diff --git a/packages/paima-sdk/paima-crypto/src/polkadot.ts b/packages/paima-sdk/paima-crypto/src/polkadot.ts index fde7c3440..7455c5282 100644 --- a/packages/paima-sdk/paima-crypto/src/polkadot.ts +++ b/packages/paima-sdk/paima-crypto/src/polkadot.ts @@ -1,5 +1,3 @@ -import { cryptoWaitReady, decodeAddress, signatureVerify } from '@polkadot/util-crypto'; -import { u8aToHex } from '@polkadot/util'; import { doLog } from '@paima/utils'; import type { IVerify } from './IVerify'; @@ -14,6 +12,10 @@ export class PolkadotCrypto implements IVerify { signature: string ): Promise => { try { + const { cryptoWaitReady, decodeAddress, signatureVerify } = await import( + '@polkadot/util-crypto' + ); + const { u8aToHex } = await import('@polkadot/util'); await cryptoWaitReady(); const publicKey = decodeAddress(userAddress); const hexPublicKey = u8aToHex(publicKey); diff --git a/packages/paima-sdk/paima-providers/src/algorand.ts b/packages/paima-sdk/paima-providers/src/algorand.ts index ad3661c96..e8746f74e 100644 --- a/packages/paima-sdk/paima-providers/src/algorand.ts +++ b/packages/paima-sdk/paima-providers/src/algorand.ts @@ -1,4 +1,4 @@ -import { PeraWalletConnect } from '@perawallet/connect'; +import type { PeraWalletConnect } from '@perawallet/connect'; import type { ActiveConnection, GameInfo, IConnector, IProvider, UserSignature } from './IProvider'; import { CryptoManager } from '@paima/crypto'; import { uint8ArrayToHexString } from '@paima/utils'; @@ -44,6 +44,7 @@ export class AlgorandConnector implements IConnector { if (name !== SupportedAlgorandWallets.PERA) { throw new UnsupportedWallet(`AlgorandProvider: unknown connection type ${name}`); } + const { PeraWalletConnect } = await import('@perawallet/connect'); const peraWallet = new PeraWalletConnect(); return await this.connectExternal(gameInfo, { metadata: { @@ -89,7 +90,7 @@ export class AlgorandProvider implements IProvider { return this.address; }; signMessage = async (message: string): Promise => { - const txn = CryptoManager.Algorand().buildAlgorandTransaction(this.getAddress(), message); + const txn = await CryptoManager.Algorand().buildAlgorandTransaction(this.getAddress(), message); const signerTx = { txn, signers: [this.getAddress()], @@ -101,7 +102,7 @@ export class AlgorandProvider implements IProvider { `[signMessageAlgorand] invalid number of signatures returned: ${signedTxs.length}` ); } - const signedTx = CryptoManager.Algorand().decodeSignedTransaction(signedTxs[0]); + const signedTx = await CryptoManager.Algorand().decodeSignedTransaction(signedTxs[0]); const signature = signedTx.sig; if (!signature) { throw new ProviderApiError(`[signMessageAlgorand] signature missing in signed Tx`); diff --git a/packages/paima-sdk/paima-providers/src/polkadot.ts b/packages/paima-sdk/paima-providers/src/polkadot.ts index 66ff85d98..f7788b2e3 100644 --- a/packages/paima-sdk/paima-providers/src/polkadot.ts +++ b/packages/paima-sdk/paima-providers/src/polkadot.ts @@ -1,9 +1,3 @@ -import { - web3Accounts, - web3Enable, - web3FromAddress, - web3FromSource, -} from '@polkadot/extension-dapp'; import type { ActiveConnection, GameInfo, IConnector, IProvider, UserSignature } from './IProvider'; import { ProviderApiError, @@ -32,6 +26,7 @@ export class PolkadotConnector implements IConnector { if (this.provider != null) { return this.provider; } + const { web3Accounts, web3Enable, web3FromAddress } = await import('@polkadot/extension-dapp'); const extensions = await web3Enable(gameInfo.gameName); if (extensions.length === 0) { throw new WalletNotFound(`[polkadot] no extension detected`); @@ -61,6 +56,8 @@ export class PolkadotConnector implements IConnector { return this.provider; } + const { web3Enable, web3FromSource } = await import('@polkadot/extension-dapp'); + await web3Enable(gameInfo.gameName); try { const injector = await web3FromSource(name);