Skip to content

Commit

Permalink
Flexible providers (#249)
Browse files Browse the repository at this point in the history
* feature: list wallet options for a provider & EIP6963

* Remove hard-coded list of wallets

* Avoid crash if no wallets installed for a specific crypto

* remove useless lowercase calls
  • Loading branch information
SebastienGllmt authored Oct 28, 2023
1 parent 058f1e4 commit 76269c8
Show file tree
Hide file tree
Showing 24 changed files with 522 additions and 361 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,5 @@
"./packages/*/*"
],
"dependencies": {
"assert-never": "^1.2.1"
}
}
3 changes: 2 additions & 1 deletion packages/batcher/address-validator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
},
"dependencies": {
"pg": "^8.7.3",
"web3": "1.10.0"
"web3": "1.10.0",
"assert-never": "^1.2.1"
},
"devDependencies": {
"@types/pg": "^8.6.5"
Expand Down
3 changes: 2 additions & 1 deletion packages/batcher/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@truffle/hdwallet-provider": "^2.1.15",
"web3": "1.10.0"
"web3": "1.10.0",
"assert-never": "^1.2.1"
}
}
1 change: 1 addition & 0 deletions packages/engine/paima-funnel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
"typescript": "^5.2.2"
},
"dependencies": {
"assert-never": "^1.2.1"
}
}
2 changes: 1 addition & 1 deletion packages/engine/paima-funnel/src/cde/erc20Deposit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default async function getCdeData(
// https://github.com/dethcrypto/TypeChain/issues/767
const events = (await timeout(
extension.contract.getPastEvents('Transfer', {
filter: { to: extension.depositAddress.toLocaleLowerCase() },
filter: { to: extension.depositAddress.toLowerCase() },
fromBlock: fromBlock,
toBlock: toBlock,
}),
Expand Down
3 changes: 2 additions & 1 deletion packages/engine/paima-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"express": "^4.18.1",
"fnv-plus": "^1.3.1",
"json-stable-stringify": "^1.0.2",
"yaml": "^2.3.1"
"yaml": "^2.3.1",
"assert-never": "^1.2.1"
},
"devDependencies": {
"@types/cors": "^2.8.12",
Expand Down
1 change: 1 addition & 0 deletions packages/engine/paima-sm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
},
"author": "Paima Studios",
"dependencies": {
"assert-never": "^1.2.1"
}
}
3 changes: 2 additions & 1 deletion packages/paima-sdk/paima-mw-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@paima/utils": "1.1.5",
"@paima/providers": "1.1.5",
"@paima/concise": "1.1.5",
"@paima/prando": "1.1.5"
"@paima/prando": "1.1.5",
"assert-never": "^1.2.1"
}
}
12 changes: 4 additions & 8 deletions packages/paima-sdk/paima-mw-core/src/endpoints/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from '../helpers/auxiliary-queries';
import { checkCardanoWalletStatus } from '../wallets/cardano';
import { checkEthWalletStatus } from '../wallets/evm';
import { specificWalletLogin, stringToWalletMode } from '../wallets/wallets';
import { specificWalletLogin } from '../wallets/wallets';
import {
getEmulatedBlocksActive,
getPostingMode,
Expand All @@ -14,6 +14,7 @@ import {
setEmulatedBlocksInactive,
} from '../state';
import type { Result, OldResult, Wallet } from '../types';
import type { LoginInfo } from '../wallets/wallet-modes';

/**
* Wrapper function for all wallet status checking functions
Expand All @@ -39,15 +40,10 @@ async function checkWalletStatus(): Promise<OldResult> {
* thus allowing the game to get past the login screen.
* @param preferBatchedMode - If true (or truthy value) even EVM wallet inputs will be batched.
*/
async function userWalletLogin(
loginType: string,
preferBatchedMode: boolean = false
): Promise<Result<Wallet>> {
async function userWalletLogin(loginInfo: LoginInfo): Promise<Result<Wallet>> {
const errorFxn = buildEndpointErrorFxn('userWalletLogin');

const walletMode = stringToWalletMode(loginType);
// Unity bridge uses 0|1 instead of booleans
const response = await specificWalletLogin(walletMode, !!preferBatchedMode);
const response = await specificWalletLogin(loginInfo);
if (!response.success) {
return response;
}
Expand Down
32 changes: 5 additions & 27 deletions packages/paima-sdk/paima-mw-core/src/endpoints/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { buildEndpointErrorFxn, PaimaMiddlewareErrorCode } from '../errors';
import {
getActiveAddress,
getChainUri,
getGameName,
getPostingInfo,
setAutomaticMode,
setBackendUri,
Expand All @@ -15,35 +14,14 @@ import {
setUnbatchedMode,
} from '../state';
import type { PostingInfo, PostingModeSwitchResult, Result, Wallet } from '../types';
import { specificWalletLogin, stringToWalletMode } from '../wallets/wallets';
import { specificWalletLogin } from '../wallets/wallets';
import { emulatedBlocksActiveOnBackend } from '../helpers/auxiliary-queries';
import { CardanoConnector, TruffleConnector } from '@paima/providers';
import { TruffleConnector } from '@paima/providers';
import HDWalletProvider from '@truffle/hdwallet-provider';
import type { LoginInfo } from '../wallets/wallet-modes';

export async function userWalletLoginWithoutChecks(
loginType: string,
preferBatchedMode = false
): Promise<Result<Wallet>> {
const walletMode = stringToWalletMode(loginType);
return await specificWalletLogin(walletMode, preferBatchedMode);
}

export async function cardanoWalletLoginEndpoint(): Promise<Result<Wallet>> {
const errorFxn = buildEndpointErrorFxn('cardanoWalletLoginEndpoint');
try {
const provider = await CardanoConnector.instance().connectSimple({
gameName: getGameName(),
gameChainId: undefined,
});
return {
success: true,
result: {
walletAddress: provider.getAddress(),
},
};
} catch (err) {
return errorFxn(PaimaMiddlewareErrorCode.CARDANO_LOGIN, err);
}
export async function userWalletLoginWithoutChecks(loginInfo: LoginInfo): Promise<Result<Wallet>> {
return await specificWalletLogin(loginInfo);
}

export async function automaticWalletLogin(privateKey: string): Promise<Result<Wallet>> {
Expand Down
3 changes: 1 addition & 2 deletions packages/paima-sdk/paima-mw-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { queryEndpoints } from './endpoints/queries';
import { utilityEndpoints } from './endpoints/utility';

import {
cardanoWalletLoginEndpoint,
retrievePostingInfo,
switchToBatchedCardanoMode,
switchToBatchedEthMode,
Expand Down Expand Up @@ -59,6 +58,7 @@ export type * from './errors';
// Only for use in game-specific middleware:
export * from './types';
export type * from './types';
export { WalletMode } from './wallets/wallet-modes';
export {
paimaEndpoints,
getBlockNumber,
Expand All @@ -83,7 +83,6 @@ export {

// NOT FOR USE IN PRODUCTION, just internal endpoints and helper functions for easier testing and debugging:
export {
cardanoWalletLoginEndpoint,
retrievePostingInfo,
switchToBatchedCardanoMode,
switchToBatchedEthMode,
Expand Down
1 change: 1 addition & 0 deletions packages/paima-sdk/paima-mw-core/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Hash, WalletAddress, UserSignature } from '@paima/utils';
export type * from './wallets/wallet-modes';

export interface PostingInfo {
address: WalletAddress;
Expand Down
41 changes: 26 additions & 15 deletions packages/paima-sdk/paima-mw-core/src/wallets/algorand.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
import type { Result, Wallet } from '../types';
import type { LoginInfoMap, Result, Wallet } from '../types';
import { PaimaMiddlewareErrorCode, buildEndpointErrorFxn } from '../errors';
import { AlgorandConnector } from '@paima/providers';
import { getGameName } from '../state';
import type { WalletMode } from './wallet-modes';
import { connectWallet } from './wallet-modes';

export async function algorandLoginWrapper(): Promise<Result<Wallet>> {
export async function algorandLoginWrapper(
loginInfo: LoginInfoMap[WalletMode.ALGORAND]
): Promise<Result<Wallet>> {
const errorFxn = buildEndpointErrorFxn('algorandLoginWrapper');

try {
const provider = await AlgorandConnector.instance().connectSimple({
gameName: getGameName(),
gameChainId: undefined,
});
return {
success: true,
result: {
walletAddress: provider.getAddress(),
},
};
} catch (err) {
return errorFxn(PaimaMiddlewareErrorCode.ALGORAND_LOGIN, err);
const gameInfo = {
gameName: getGameName(),
gameChainId: undefined, // Not needed because of batcher
};
const loginResult = await connectWallet(
'algorandLoginWrapper',
errorFxn,
PaimaMiddlewareErrorCode.ALGORAND_LOGIN,
loginInfo,
AlgorandConnector.instance(),
gameInfo
);
if (loginResult.success === false) {
return loginResult;
}
return {
success: true,
result: {
walletAddress: loginResult.result.getAddress(),
},
};
}
92 changes: 28 additions & 64 deletions packages/paima-sdk/paima-mw-core/src/wallets/cardano.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import type { OldResult, Result, Wallet } from '../types';
import {
buildEndpointErrorFxn,
PaimaMiddlewareErrorCode,
FE_ERR_SPECIFIC_WALLET_NOT_INSTALLED,
} from '../errors';
import { WalletMode } from './wallet-modes';
import { CardanoConnector, UnsupportedWallet, WalletNotFound } from '@paima/providers';
import type { LoginInfoMap, OldResult, Result, Wallet } from '../types';
import { buildEndpointErrorFxn, PaimaMiddlewareErrorCode } from '../errors';
import type { WalletMode } from './wallet-modes';
import { connectWallet } from './wallet-modes';
import { CardanoConnector } from '@paima/providers';
import { getGameName } from '../state';

export async function checkCardanoWalletStatus(): Promise<OldResult> {
Expand All @@ -21,63 +18,30 @@ export async function checkCardanoWalletStatus(): Promise<OldResult> {
return { success: true, message: '' };
}

function cardanoWalletModeToName(walletMode: WalletMode): string {
switch (walletMode) {
case WalletMode.CARDANO_FLINT:
return 'flint';
case WalletMode.CARDANO_NUFI:
return 'nufi';
case WalletMode.CARDANO_NAMI:
return 'nami';
case WalletMode.CARDANO_ETERNL:
return 'eternl';
default:
return '';
}
}

export async function cardanoLoginWrapper(walletMode: WalletMode): Promise<Result<Wallet>> {
export async function cardanoLoginWrapper(
loginInfo: LoginInfoMap[WalletMode.CARDANO]
): Promise<Result<Wallet>> {
const errorFxn = buildEndpointErrorFxn('cardanoLoginWrapper');
console.log('[cardanoLoginWrapper] window.cardano:', (window as any).cardano);

let specificWalletName: string | undefined = undefined;
if (walletMode !== WalletMode.CARDANO) {
console.log(`[cardanoLoginWrapper] Attempting to log into ${specificWalletName}`);
specificWalletName = cardanoWalletModeToName(walletMode);
if (!specificWalletName) {
return errorFxn(PaimaMiddlewareErrorCode.CARDANO_WALLET_NOT_INSTALLED);
}
} else {
console.log(`[cardanoLoginWrapper] Attempting to log into any Cardano wallet`);
}

try {
const gameInfo = {
gameName: getGameName(),
gameChainId: undefined,
};
const provider =
specificWalletName == null
? await CardanoConnector.instance().connectSimple(gameInfo)
: await CardanoConnector.instance().connectNamed(gameInfo, specificWalletName);
return {
success: true,
result: {
walletAddress: provider.getAddress().toLocaleLowerCase(),
},
};
} catch (err) {
if (err instanceof WalletNotFound || err instanceof UnsupportedWallet) {
return errorFxn(
PaimaMiddlewareErrorCode.CARDANO_WALLET_NOT_INSTALLED,
undefined,
FE_ERR_SPECIFIC_WALLET_NOT_INSTALLED
);
}
console.log(
`[cardanoLoginWrapper] Error while logging into wallet ${specificWalletName ?? 'Cardano'}`
);
return errorFxn(PaimaMiddlewareErrorCode.CARDANO_LOGIN, err);
// TODO: improve error differentiation
const gameInfo = {
gameName: getGameName(),
gameChainId: undefined, // Not needed because of batcher
};
const loginResult = await connectWallet(
'cardanoLoginWrapper',
errorFxn,
PaimaMiddlewareErrorCode.CARDANO_LOGIN,
loginInfo,
CardanoConnector.instance(),
gameInfo
);
if (loginResult.success === false) {
return loginResult;
}
return {
success: true,
result: {
walletAddress: loginResult.result.getAddress(),
},
};
}
Loading

0 comments on commit 76269c8

Please sign in to comment.