diff --git a/deno.lock b/deno.lock index 8188ee630..91810bce9 100644 --- a/deno.lock +++ b/deno.lock @@ -13759,6 +13759,11 @@ "npm:js-sha3@~0.9.3" ] }, + "packages/paima-sdk/test": { + "dependencies": [ + "npm:@sinclair/typebox@~0.34.30" + ] + }, "packages/paima-sdk/utils": { "dependencies": [ "npm:@coderspirit/nominal@^4.1.1", diff --git a/packages/paima-sdk/config/src/schema/utils.ts b/packages/paima-sdk/config/src/schema/utils.ts index 462cf64c7..c3c531770 100644 --- a/packages/paima-sdk/config/src/schema/utils.ts +++ b/packages/paima-sdk/config/src/schema/utils.ts @@ -122,3 +122,24 @@ export class ConfigSchema< }) as any; }; } + +export function createSchema< + Base extends ConfigSchema, + Required extends ObjectLike, + Optional extends ObjectLike, +>( + params: { + base: Base; + required: Required; + optional: Optional; + }, +) { + const config = params.base.cloneMerge({ + required: params.required, + optional: params.optional, + }); + const optionalProps = config.allProperties(false); + const allProps = config.allProperties(true); + + return { optionalProps, allProps }; +} diff --git a/packages/paima-sdk/test/deno.json b/packages/paima-sdk/test/deno.json new file mode 100644 index 000000000..4bb24f468 --- /dev/null +++ b/packages/paima-sdk/test/deno.json @@ -0,0 +1,8 @@ +{ + "name": "@paima/test", + "version": "0.3.0", + "exports": "./src/mod.ts", + "imports": { + "@sinclair/typebox": "npm:@sinclair/typebox@^0.34.30" + } +} diff --git a/packages/paima-sdk/test/src/base.ts b/packages/paima-sdk/test/src/base.ts new file mode 100644 index 000000000..57eab2b88 --- /dev/null +++ b/packages/paima-sdk/test/src/base.ts @@ -0,0 +1,38 @@ +import { ConfigPrimitivePayloadType, ConfigPrimitiveType } from "@paima/config"; +import { type TIntersect, type TObject, type TSchema } from "@sinclair/typebox"; +import type { BlockNumber } from "@paima/utils"; + +export interface EvmPrimitive { + data: Data; + fetchData: () => void; // TODO + createViews: () => void; + createScheduledData: ( + paima_block_height: BlockNumber, + payload: Data["payloadType"], + ) => void; +} + +export type BasePrimitivePayloadType = { + type: ConfigPrimitivePayloadType; + payload: TObject; +}; +export abstract class BasePrimitive< + Data extends { payloadType: BasePrimitivePayloadType }, +> { + abstract fetchData(): void; // TODO + createViews(): void {} + abstract createScheduledData( + paima_block_height: BlockNumber, + payload: Data["payloadType"], + ): void; +} + +export interface PrimitiveData { + readonly payloadType: BasePrimitivePayloadType; + readonly schema: { + required: TIntersect; + optional: TIntersect; + }; + readonly primitiveType: ConfigPrimitiveType; + readonly transitions: Record; +} diff --git a/packages/paima-sdk/test/src/builtin.ts b/packages/paima-sdk/test/src/builtin.ts new file mode 100644 index 000000000..536576d62 --- /dev/null +++ b/packages/paima-sdk/test/src/builtin.ts @@ -0,0 +1,83 @@ +import { + ConfigPrimitivePayloadType, + ConfigPrimitiveType, + createSchema, + PrimitiveConfigBaseEvm, +} from "@paima/config"; +import { pickAll } from "@paima/utils"; +import { TypeboxHelpers } from "@paima/utils"; +import { type Static, Type } from "@sinclair/typebox"; +import type { BlockNumber } from "@paima/utils"; +import { Value } from "@sinclair/typebox/value"; +import { BasePrimitive } from "./base.ts"; + +const payloadType = { + type: ConfigPrimitivePayloadType.Transfer, + payload: Type.Object({ + from: TypeboxHelpers.Evm.Address, + to: TypeboxHelpers.Evm.Address, + value: TypeboxHelpers.Uint256, + }), +}; +const PrimitiveDataErc20 = { + payloadType, + schema: createSchema({ + base: PrimitiveConfigBaseEvm, + required: Type.Object({ + type: Type.Literal(ConfigPrimitiveType.EvmRpcERC20), + contractAddress: TypeboxHelpers.Evm.Address, + }), + optional: Type.Object({ + scheduledPrefix: Type.String(), + }), + }), + primitiveType: ConfigPrimitiveType.EvmRpcERC20, + transitions: { + transferScheduledPrefix: pickAll(["from", "to", "value"]).from( + payloadType.payload, + ), + }, +}; + +type DataType = typeof PrimitiveDataErc20; +class Erc20Primitive extends BasePrimitive { + config: Static; + data: DataType; + + constructor( + props: Static, + ) { + super(); + this.data = PrimitiveDataErc20; + this.config = Value.Default( + PrimitiveDataErc20.schema.allProps, + props, + ) as typeof this.config; + } + override createViews = () => { + // TODO: views for erc20 + }; + fetchData = () => { + }; + + createScheduledData( + paima_block_height: BlockNumber, + payload: DataType["payloadType"], + ): void { + console.log(paima_block_height, payload); + // yield* World.resolve(insertPrimitiveAccounting, { + // primitive_name: name, + // paima_block_height: paima_block_height, + // payload_type: ConfigPrimitiveAccountingPayloadType.Transfer, + // payload: clearBigInts(payload) satisfies PayloadOf< + // typeof PrimitiveEvmRpcErc20TransferAccounting + // >, + // }); + } +} + +declare module "@paima/test" { + interface SomeGlobalNamespace { + Erc20Primitive: typeof Erc20Primitive; + } +} diff --git a/packages/paima-sdk/test/src/mod.ts b/packages/paima-sdk/test/src/mod.ts new file mode 100644 index 000000000..ee3fe2136 --- /dev/null +++ b/packages/paima-sdk/test/src/mod.ts @@ -0,0 +1 @@ +export type { RegisteredComponents } from "./builtin.ts"; diff --git a/packages/paima-sdk/test2/deno.json b/packages/paima-sdk/test2/deno.json new file mode 100644 index 000000000..c1b1da455 --- /dev/null +++ b/packages/paima-sdk/test2/deno.json @@ -0,0 +1,7 @@ +{ + "name": "@paima/test2", + "version": "0.3.0", + "exports": "./src/mod.ts", + "imports": { + } +} diff --git a/packages/paima-sdk/test2/src/mod.ts b/packages/paima-sdk/test2/src/mod.ts new file mode 100644 index 000000000..4b3e5347d --- /dev/null +++ b/packages/paima-sdk/test2/src/mod.ts @@ -0,0 +1,5 @@ +import type { SomeGlobalNamespace } from "@paima/test"; + +type ComponentName = keyof SomeGlobalNamespace; + +const foo: ComponentName = "Erc20Primitive"; diff --git a/packages/paima-sdk/utils/src/types/utils.ts b/packages/paima-sdk/utils/src/types/utils.ts index 691ddc929..3fb3d57b6 100644 --- a/packages/paima-sdk/utils/src/types/utils.ts +++ b/packages/paima-sdk/utils/src/types/utils.ts @@ -58,3 +58,12 @@ export function keysOf( ): Key[] { return Object.keys(obj) as Key[]; } + +export function clearBigInts(value: T): T { + return JSON.parse( + JSON.stringify( + value, + (_, v) => typeof v === "bigint" ? v.toString() : v, + ), + ); +}