Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make some APIs more flexible and fix corner-case encoding bugs #439

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
39 changes: 27 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions packages/node-sdk/paima-db/src/delegate-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
getDelegationsToWithAddress,
getMainAddressFromAddress,
} from './sql/wallet-delegation.queries.js';
import type { PoolClient, Notification, Client } from 'pg';
import type { Notification, Client } from 'pg';
import type { IDatabaseConnection } from '@pgtyped/runtime/lib/tag';

export type WalletDelegate = { address: string; id: number };
Expand All @@ -29,7 +29,7 @@ export async function getMainAddress(
_address: string,
DBConn: IDatabaseConnection
): Promise<WalletDelegate> {
const address = _address.toLocaleLowerCase();
const address = _address.toLowerCase();
let addressMapping: WalletDelegate | undefined = addressCache.get(address);
if (useAddressCache && addressMapping) return addressMapping;

Expand All @@ -55,13 +55,13 @@ export async function getMainAddress(

export async function getRelatedWallets(
_address: string,
DBConn: PoolClient
DBConn: IDatabaseConnection
): Promise<{
from: IGetDelegationsFromWithAddressResult[];
to: IGetDelegationsToWithAddressResult[];
id: number;
}> {
const address = _address.toLocaleLowerCase();
const address = _address.toLowerCase();
const [addressResult] = await getAddressFromAddress.run({ address }, DBConn);
if (!addressResult) {
return { from: [], to: [], id: NO_USER_ID };
Expand Down
4 changes: 2 additions & 2 deletions packages/node-sdk/paima-db/src/sql/achievements.queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export interface ISetAchievementProgressQuery {
result: ISetAchievementProgressResult;
}

const setAchievementProgressIR: any = {"usedParamSet":{"wallet":true,"name":true,"completed_date":true,"progress":true,"total":true},"params":[{"name":"wallet","required":true,"transform":{"type":"scalar"},"locs":[{"a":89,"b":96}]},{"name":"name","required":true,"transform":{"type":"scalar"},"locs":[{"a":99,"b":104}]},{"name":"completed_date","required":false,"transform":{"type":"scalar"},"locs":[{"a":107,"b":121}]},{"name":"progress","required":false,"transform":{"type":"scalar"},"locs":[{"a":124,"b":132}]},{"name":"total","required":false,"transform":{"type":"scalar"},"locs":[{"a":135,"b":140}]}],"statement":"INSERT INTO achievement_progress (wallet, name, completed_date, progress, total)\nVALUES (:wallet!, :name!, :completed_date, :progress, :total)\nON CONFLICT (wallet, name)\nDO UPDATE SET\n completed_date = EXCLUDED.completed_date,\n progress = EXCLUDED.progress,\n total = EXCLUDED.total"};
const setAchievementProgressIR: any = {"usedParamSet":{"wallet":true,"name":true,"completed_date":true,"progress":true,"total":true},"params":[{"name":"wallet","required":true,"transform":{"type":"scalar"},"locs":[{"a":89,"b":96}]},{"name":"name","required":true,"transform":{"type":"scalar"},"locs":[{"a":99,"b":104}]},{"name":"completed_date","required":false,"transform":{"type":"scalar"},"locs":[{"a":107,"b":121}]},{"name":"progress","required":false,"transform":{"type":"scalar"},"locs":[{"a":124,"b":132}]},{"name":"total","required":false,"transform":{"type":"scalar"},"locs":[{"a":135,"b":140}]}],"statement":"INSERT INTO achievement_progress (wallet, name, completed_date, progress, total)\nVALUES (:wallet!, :name!, :completed_date, :progress, :total)\nON CONFLICT (wallet, name)\nDO UPDATE SET\n completed_date = LEAST(achievement_progress.completed_date, EXCLUDED.completed_date::TIMESTAMP),\n progress = EXCLUDED.progress,\n total = EXCLUDED.total"};

/**
* Query generated from SQL:
Expand All @@ -64,7 +64,7 @@ const setAchievementProgressIR: any = {"usedParamSet":{"wallet":true,"name":true
* VALUES (:wallet!, :name!, :completed_date, :progress, :total)
* ON CONFLICT (wallet, name)
* DO UPDATE SET
* completed_date = EXCLUDED.completed_date,
* completed_date = LEAST(achievement_progress.completed_date, EXCLUDED.completed_date::TIMESTAMP),
* progress = EXCLUDED.progress,
* total = EXCLUDED.total
* ```
Expand Down
2 changes: 1 addition & 1 deletion packages/node-sdk/paima-db/src/sql/achievements.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ INSERT INTO achievement_progress (wallet, name, completed_date, progress, total)
VALUES (:wallet!, :name!, :completed_date, :progress, :total)
ON CONFLICT (wallet, name)
DO UPDATE SET
completed_date = EXCLUDED.completed_date,
completed_date = LEAST(achievement_progress.completed_date, EXCLUDED.completed_date::TIMESTAMP),
progress = EXCLUDED.progress,
total = EXCLUDED.total;
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ export class EmulatedBlocksFunnel extends BaseFunnel {
processingQueue[processingQueue.length - 1]?.blockNumber ?? 0
),
latestFetchedTimestamp: Math.max(
parseInt(res.second_timestamp, 10),
Number(res.second_timestamp),
processingQueue[processingQueue.length - 1]?.timestamp ?? 0
),
};
Expand Down
2 changes: 1 addition & 1 deletion packages/node-sdk/paima-runtime/src/runtime-loops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ async function getPresyncStartBlockheight(
const caip2 = caip2PrefixFor(config[network]);
result[caip2] = freshPresyncStart;

const latestPresyncBlockheight = await gameStateMachine.getPresyncBlockHeight(network);
const latestPresyncBlockheight = await gameStateMachine.getPresyncBlockHeight(caip2);

if (latestPresyncBlockheight > 0) {
result[caip2] = latestPresyncBlockheight + 1;
Expand Down
25 changes: 13 additions & 12 deletions packages/node-sdk/paima-runtime/src/snapshots.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as fs from 'fs/promises';

import { exec } from 'child_process';
import type { ExecException } from 'child_process';
import { execFile } from 'child_process';
import type { ExecFileException } from 'child_process';
import { doLog, logError } from '@paima/utils';

const SNAPSHOT_INTERVAL = 21600;
Expand Down Expand Up @@ -42,18 +42,19 @@ async function getNewestFilename(dir: string): Promise<string> {
}

async function saveSnapshot(blockHeight: number): Promise<void> {
const username = process.env.DB_USER;
const password = process.env.DB_PW;
const database = process.env.DB_NAME;
const host = process.env.DB_HOST;
const port = process.env.DB_PORT || '5432';
const fileName = `paima-snapshot-${blockHeight}.sql`;
doLog(`[paima-runtime::snapshots] Saving Snapshot: ${fileName}`);
exec(
`pg_dump --dbname=postgresql://${username}:${password}@${host}:${port}/${database} -f ${snapshotPath(
fileName
)}`,
(error: ExecException | null, stdout: string, stderr: string) => {
const url = Object.assign(new URL('postgresql://'), {
hostname: process.env.DB_HOST,
port: process.env.DB_PORT || '5432',
username: process.env.DB_USER,
password: process.env.DB_PW,
pathname: process.env.DB_NAME,
} satisfies Partial<URL>).toString();
execFile(
'pg_dump',
[`--dbname=${url}`, '-f', snapshotPath(fileName)],
(error: ExecFileException | null, stdout: string, stderr: string) => {
if (error) {
doLog(`[paima-runtime::snapshots] Error saving snapshot: ${stderr}`);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/node-sdk/paima-sm/src/cde-erc721-transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default async function processErc721Datum(
const { to, tokenId, from } = cdeDatum.payload;
const toAddr = to.toLowerCase();

const isBurn = Boolean(toAddr.toLocaleLowerCase().match(/^0x0+(dead)?$/g));
const isBurn = Boolean(toAddr.toLowerCase().match(/^0x0+(dead)?$/g));

const updateList: SQLUpdate[] = [];
try {
Expand Down
8 changes: 4 additions & 4 deletions packages/node-sdk/paima-sm/src/delegate-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class DelegateWallet {

/* Generate Plaintext Message */
private generateMessage(internalMessage: string = ''): string {
return `${DelegateWallet.DELEGATE_WALLET_PREFIX}${DelegateWallet.SEP}${internalMessage.toLocaleLowerCase()}`;
return `${DelegateWallet.DELEGATE_WALLET_PREFIX}${DelegateWallet.SEP}${internalMessage.toLowerCase()}`;
}

private validateSender(to: string, from: string, realAddress: string): void {
Expand Down Expand Up @@ -305,7 +305,7 @@ export class DelegateWallet {
this.verifySignature(from, this.generateMessage(to), from_signature),
this.verifySignature(to, this.generateMessage(from), to_signature),
]);
await this.cmdDelegate(from.toLocaleLowerCase(), to.toLocaleLowerCase());
await this.cmdDelegate(from.toLowerCase(), to.toLowerCase());
doLog(`Delegate Wallet ${from.substring(0, 8)}... -> ${to.substring(0, 8)}...`);
return true;
}
Expand All @@ -319,14 +319,14 @@ export class DelegateWallet {
this.verifySignature(from, this.generateMessage(to), from_signature),
this.verifySignature(to, this.generateMessage(from), to_signature),
]);
await this.cmdMigrate(from.toLocaleLowerCase(), to.toLocaleLowerCase());
await this.cmdMigrate(from.toLowerCase(), to.toLowerCase());

doLog(`Migrate Wallet ${from.substring(0, 8)}... -> ${to.substring(0, 8)}...`);
return true;
}
case 'cancelDelegations': {
const { to } = parsed.args;
await this.cmdCancelDelegations(userAddress.toLocaleLowerCase(), to.toLocaleLowerCase());
await this.cmdCancelDelegations(userAddress.toLowerCase(), to.toLowerCase());
doLog(
`Cancel Delegate ${userAddress.substring(0, 8)}... -> ${to ? to.substring(0, 8) + '...' : '*'}`
);
Expand Down
6 changes: 3 additions & 3 deletions packages/node-sdk/paima-sm/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ interface CdeDatumDynamicEvmPrimitivePayload {
targetConfig:
| {
type: CdeEntryTypeName.ERC721;
scheduledPrefix: string;
scheduledPrefix?: string | undefined;
burnScheduledPrefix?: string | undefined;
}
| {
Expand Down Expand Up @@ -246,7 +246,7 @@ export interface CdeErc721MintDatum extends CdeEvmDatumBase {
cdeDatumType: ChainDataExtensionDatumType.ERC721Mint;
payload: CdeDatumErc721MintPayload;
contractAddress: string;
scheduledPrefix: string;
scheduledPrefix: string | undefined;
}

export interface CdeErc20DepositDatum extends CdeEvmDatumBase {
Expand Down Expand Up @@ -405,7 +405,7 @@ export const ChainDataExtensionErc721Config = Type.Intersect([
Type.Object({
type: Type.Literal(CdeEntryTypeName.ERC721),
contractAddress: EvmAddress,
scheduledPrefix: Type.String(),
scheduledPrefix: Type.Optional(Type.String()),
burnScheduledPrefix: Type.Optional(Type.String()),
}),
]);
Expand Down
15 changes: 7 additions & 8 deletions packages/paima-sdk/paima-crypto/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,17 @@
"build": "tsc --build tsconfig.build.json",
"test": "vitest run"
},
"devDependencies": {},
"dependencies": {
"web3": "1.10.0",
"web3-utils": "1.10.0",
"@cardano-foundation/cardano-verify-datasignature": "^1.0.11",
"algosdk": "^2.3.0",
"tweetnacl": "^1.0.3",
"@paima/utils": "5.0.0",
"@polkadot/util": "^12.6.2",
"@polkadot/util-crypto": "^12.6.2",
"algosdk": "^2.3.0",
"bech32": "^2.0.0",
"@paima/utils": "5.0.0",
"mina-signer": "^2.1.1",
"bs58check": "^4.0.0"
"bs58check": "^4.0.0",
"mina-signer": "^3.0.7",
"tweetnacl": "^1.0.3",
"web3": "1.10.0",
"web3-utils": "1.10.0"
}
}
2 changes: 1 addition & 1 deletion packages/paima-sdk/paima-crypto/src/mina.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class MinaCrypto implements IVerify {
return false;
}

const Client = (await import('mina-signer')).default;
const { default: Client } = await import('mina-signer');

const signerClient = new Client({ network: network as NetworkId });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export class WalletConnectHelper {
private static readonly SEP = ':';

public buildMessageToSign(subMessage: string): string {
return `${WalletConnectHelper.DELEGATE_WALLET_PREFIX}${WalletConnectHelper.SEP}${subMessage.toLocaleLowerCase()}`;
return `${WalletConnectHelper.DELEGATE_WALLET_PREFIX}${WalletConnectHelper.SEP}${subMessage.toLowerCase()}`;
}

private getProvider(walletType: AddressType): IProvider<unknown> {
Expand Down
32 changes: 16 additions & 16 deletions packages/paima-sdk/paima-mw-core/src/helpers/posting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ export async function postConciselyEncodedData(
}
}

async function getAdjustedHeight(deploymentChainBlockHeight: number): Promise<number> {
async function getAdjustedHeight(deploymentChainBlockHeight: number): Promise<Result<number>> {
const errorFxn = buildEndpointErrorFxn('getAdjustedHeight');

const emulatedActive =
getEmulatedBlocksActive() ??
(await emulatedBlocksActiveOnBackend().then(
Expand All @@ -221,18 +223,22 @@ async function getAdjustedHeight(deploymentChainBlockHeight: number): Promise<nu

if (emulatedActive) {
const BLOCK_DELAY = 1000;
// -1 here means the block isn't part of the chain yet so we can't know the mapping
const BLOCK_NOT_PART_OF_CHAIN_YET = -1;

// TODO: magic number. -1 here means the block isn't part of the chain yet so we can't know the mapping
let block = -1;
while (block === -1) {
for (let i = 0; i < BATCHER_RETRIES; ++i) {
const remote = await deploymentChainBlockHeightToEmulated(deploymentChainBlockHeight);
if (remote.success === false || remote.result === -1) {
await wait(BLOCK_DELAY);
if (remote.success === true && remote.result !== BLOCK_NOT_PART_OF_CHAIN_YET) {
return remote;
}
await wait(BLOCK_DELAY);
}
return block;
return errorFxn(
PaimaMiddlewareErrorCode.ERROR_POSTING_TO_BATCHER,
"emulated block didn't succeed in time"
);
} else {
return deploymentChainBlockHeight;
return { success: true, result: deploymentChainBlockHeight };
}
}

Expand All @@ -251,10 +257,7 @@ async function postString(
TX_VERIFICATION_RETRY_DELAY,
TX_VERIFICATION_RETRY_COUNT
);
return {
success: true,
result: await getAdjustedHeight(deploymentChainBlockHeight),
};
return await getAdjustedHeight(deploymentChainBlockHeight);
} catch (err) {
return errorFxn(PaimaMiddlewareErrorCode.ERROR_POSTING_TO_CHAIN, err);
}
Expand Down Expand Up @@ -343,10 +346,7 @@ async function verifyBatcherSubmission(inputHash: string): Promise<Result<number
FE_ERR_BATCHER_REJECTED_INPUT
);
} else if (status.status === 'posted') {
return {
success: true,
result: await getAdjustedHeight(status.block_height),
};
return await getAdjustedHeight(status.block_height);
}
} catch (err) {
errorFxn(PaimaMiddlewareErrorCode.INVALID_RESPONSE_FROM_BATCHER, err);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ export function buildBackendQuery(endpoint: string, options: QueryOptions): stri
}

export function buildQuery(endpoint: string, options: QueryOptions): string {
const optStrings: string[] = [];
for (let opt in options) {
const valString = queryValueToString(options[opt]);
optStrings.push(`${opt}=${valString}`);
}
if (optStrings.length === 0) {
const queryString = new URLSearchParams(
Object.entries(options).map(([k, v]) => [k, queryValueToString(v)])
).toString();
if (queryString.length === 0) {
return endpoint;
} else {
return `${endpoint}?${optStrings.join('&')}`;
return `${endpoint}?${queryString}`;
}
}

Expand Down