Skip to content

Commit

Permalink
ledger: Boyscout compile errors for multi-backend adaptation
Browse files Browse the repository at this point in the history
  • Loading branch information
Norbert Dzikowski committed Aug 22, 2023
1 parent 1982b6c commit 308e47a
Show file tree
Hide file tree
Showing 15 changed files with 212 additions and 358 deletions.
2 changes: 1 addition & 1 deletion src/api/responses/balanceproof.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Address } from "#erdstall/ledger";
import {
Erdstall,
Erdstall__factory,
} from "#erdstall/ledger/backend/contracts";
} from "#erdstall/ledger/backend/ethereum/contracts";

import * as test from "#erdstall/test";
import { Environment, setupEnv } from "#erdstall/test/ledger";
Expand Down
3 changes: 2 additions & 1 deletion src/api/transactions/trade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
} from "#erdstall/export/typedjson";
import { ABIEncoder, ABIPacked } from "#erdstall/api/util";
import { Signature } from "#erdstall/api";
import { Signer, utils } from "ethers";
import { utils } from "ethers";
import { Signer } from "#erdstall/ledger/backend";

@jsonObject
export class TradeFees {
Expand Down
3 changes: 2 additions & 1 deletion src/api/transactions/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import {
Serializable,
jsonBigIntMember,
} from "#erdstall/export/typedjson";
import { utils, Signer } from "ethers";
import { utils } from "ethers";
import { ETHZERO } from "#erdstall/ledger/assets";
import { Signer } from "#erdstall/ledger/backend";

const transactionImpls = new Map<string, Serializable<Transaction>>();
const transactionTypeName = "Transaction";
Expand Down
57 changes: 57 additions & 0 deletions src/client.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// SPDX-License-Identifier: Apache-2.0
"use strict";

import { ErdstallSession, ErdstallClient, Client, Session } from "#erdstall";
import { expect } from "chai";

describe("ErdstallClient", () => {
const enclaveConn = new URL("http://localhost:8080");
const cl: ErdstallClient<["ethereum", "substrate"]> = new Client<
["ethereum", "substrate"]
>(
enclaveConn,
{
backend: "ethereum",
encConn: enclaveConn,
provider: {} as any,
},
{
backend: "substrate",
arg: 420,
},
);

cl.on("Withdrawn", (e) => {});
});

describe("ErdstallSession", () => {
const singleSession: ErdstallSession<["ethereum"]> = new Session<
["ethereum"]
>({
backend: "ethereum",
encConn: new URL("http://localhost:8545"),
provider: {} as any,
signer: {} as any,
address: {} as any,
});

const _addr = singleSession.erdstall();

const multiSession = new Session<["ethereum", "substrate"]>(
{
backend: "ethereum",
encConn: new URL("http://localhost:8545"),
provider: {} as any,
signer: {} as any,
address: {} as any,
},
{
backend: "substrate",
arg: 420,
},
);

const _multiAddr = multiSession.erdstall();

singleSession.on("Withdrawn", (e) => {});
});
94 changes: 67 additions & 27 deletions src/e2e/sdk_actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Session, Client } from "#erdstall";
import {
PerunArt__factory,
PerunToken__factory,
} from "#erdstall/ledger/backend/contracts";
} from "#erdstall/ledger/backend/ethereum/contracts";
import {
Transfer,
Mint,
Expand All @@ -19,9 +19,17 @@ import {

import { ethers, utils } from "ethers";
import { PERUN_ADDR, PART_ADDR } from "./parameters";
import {
mkDefaultEthereumClientConstructor,
mkDefaultEthereumSessionConstructor,
} from "#erdstall/ledger/backend/ethereum";
import { SubstrateClient } from "#erdstall/ledger/backend/substrate";

export type SDKActions = typeof sdkActions;

// The list of backends used for this test trace.
export type TestBackends = ["ethereum", "substrate"];

// sdkActions shows how to use the SDK for each step in a hypothetical
// scenario. Each key stands for one step a user might do when acting within
// the Erdstall system and shows how to assemble required parameter structures
Expand All @@ -38,7 +46,7 @@ export const sdkActions = {
nodeUrl: string,
signer: ethers.Signer,
operatorUrl: URL,
): Promise<Session> => {
): Promise<Session<TestBackends>> => {
// First we need a provider which allows the SDK to communicate with the
// underlying ledger. In the case of creating an `ErdstallClient` simply
// creating the provider or querying it from the environment (e.g. MetaMask
Expand All @@ -47,7 +55,16 @@ export const sdkActions = {

// Using the provider and the URL for the operator allows creating an
// `ErdstallClient`.
const client = new Client(provider, operatorUrl);
// const client = new Client(provider, operatorUrl);
const client = new Client<TestBackends>(
operatorUrl,
mkDefaultEthereumClientConstructor(provider),
{
backend: "substrate",
arg: 42,
initializer: (_c) => new SubstrateClient(42),
},
);
// One could use this readonly client to listen for various events within
// Erdstall by registering callbacks before issuing the
// `client.initialize()` call.
Expand All @@ -61,7 +78,18 @@ export const sdkActions = {
// calling the `provider.getSigner()` method (if the user has granted
// access to your app using his account).
const userAddr = Address.fromString(await signer.getAddress());
const session = new Session(userAddr, signer, operatorUrl);
// const session = new Session(userAddr, signer, operatorUrl);
const session = new Session<TestBackends>(
userAddr,
operatorUrl,
signer,
mkDefaultEthereumSessionConstructor(signer),
{
backend: "substrate",
arg: 42,
initializer: (_c) => new SubstrateClient(42),
},
);

// We could now proactively set eventhandlers in place:
//
Expand Down Expand Up @@ -93,6 +121,11 @@ export const sdkActions = {
});

// (Onchain) Erdstall handlers:
//
// The origin of each on-chain event is tagged in each event under the
// event.source field.
// If your Session is defined as `Session<["ethereum" | "substrate"]>`, the
// `event.source` field has the type `"ethereum" | "substrate"`.
session.on("TokenTypeRegistered", (_tokenTypeRegisteredEvent) => {
// A new token type with its token holder contract was registered on the
// Erdstall smart contract.
Expand Down Expand Up @@ -124,19 +157,23 @@ export const sdkActions = {
return session;
},

initialize: async (session: Session) => {
initialize: async (session: Session<TestBackends>) => {
// Initialize the session. This connects us to the operator and grants us
// the ability to extend our subscriptions in the next step.
await session.initialize();
},

// Subscribing ensures that the `ErdstallClient` or `ErdstallSession`
// receives events for phaseshifts, balanceproofs and tx-receipts.
subscribe: async (session: Session) => {
subscribe: async (session: Session<TestBackends>) => {
return session.subscribeSelf();
},

deposit: async (session: Session, ethAmount: bigint, prnAmount: bigint) => {
deposit: async (
session: Session<TestBackends>,
ethAmount: bigint,
prnAmount: bigint,
) => {
// Erdstall balances are abstract `Assets`. These assets contain individual
// assets of the `Asset` type. Currently the SDK supports two types of assets:
//
Expand All @@ -157,6 +194,7 @@ export const sdkActions = {
);

const { stages, numStages: _numStages } = await session.deposit(
"ethereum",
depositBal,
);
// Depositing is a multi-stage process. ERC20 tokens like PRN have to be
Expand Down Expand Up @@ -184,8 +222,8 @@ export const sdkActions = {
},

offchainTransfer: async (
alice: Session,
bob: Session,
alice: Session<TestBackends>,
bob: Session<TestBackends>,
prnAmount: bigint,
): Promise<void> => {
const amount = new Assets({
Expand Down Expand Up @@ -253,7 +291,7 @@ export const sdkActions = {
});
},

leave: async (session: Session) => {
leave: async (session: Session<TestBackends>) => {
// `leave` is a convenience function for first `exit`ing the Erdstall
// system and afterwards `withdrawing` all available funds for the user.
// So alternatively, if more control is required:
Expand All @@ -265,13 +303,13 @@ export const sdkActions = {
// -- callback!
//
// const { stages } = await session.withdraw(exitProof);
const { stages } = await session.leave();
const { stages } = await session.leave("ethereum");
for await (const [_name, stage] of stages) {
await stage.wait();
}
},

mint: async (session: Session, nftID: bigint) => {
mint: async (session: Session<TestBackends>, nftID: bigint) => {
// Offchain minting is simply a matter of passing an ERC721 contract
// address and an ID (unique!). Currently it is possible to mint for any
// contract offchain which is registered in Erdstall and counts as an
Expand All @@ -280,8 +318,8 @@ export const sdkActions = {
},

trade: async (
charlie: Session,
dagobert: Session,
charlie: Session<TestBackends>,
dagobert: Session<TestBackends>,
charlieNft: bigint,
wantedPrnAmount: bigint,
) => {
Expand Down Expand Up @@ -324,7 +362,7 @@ export const sdkActions = {
return (await dagobert.acceptTrade(tradeOffer)).receipt;
},

burn: async (dagobert: Session, formerCharlieNft: bigint) => {
burn: async (dagobert: Session<TestBackends>, formerCharlieNft: bigint) => {
// Burning a NFT requires being the owner of it. Since Charlie transferred
// his NFT in the step before, Dagobert is now able to do as he pleases.
// Maybe he was not a fan of monkeys and now wants some lit whales.
Expand All @@ -337,10 +375,10 @@ export const sdkActions = {
},

leavingAndSeeFundsOnchain: async function (
session: Session,
session: Session<TestBackends>,
provider: ethers.providers.Provider,
) {
const { stages } = await session.leave();
const { stages } = await session.leave("ethereum");
for await (const [, stage] of stages) {
await stage.wait();
}
Expand All @@ -354,16 +392,18 @@ export const sdkActions = {
// Erdstall related contracts, which frees you of the burden to come up
// with bindings on your own.

// The SDK provides a convenience field for on chain calls which will grow
// over time. E.g.
[PERUN_ADDR, PART_ADDR]
.map((addr) => addr.toString())
.map((addr) => {
session.onChainQuerier.queryTokensOwnedByAddress(
addr,
session.address.toString(),
);
});
// TODO: REINTRODUCE
// // The SDK provides a convenience field for on chain calls which will grow
// // over time. E.g.
// [PERUN_ADDR, PART_ADDR]
// .map((addr) => addr.toString())
// .map((addr) => {
// session.onChainQuerier.queryTokensOwnedByAddress(
// "ethereum",
// addr,
// session.address.toString(),
// );
// });

// The tokenProvider can be used to query information about tokens related
// to Erdstall. The necessary `erdstallAddr` for these calls can be
Expand Down
6 changes: 3 additions & 3 deletions src/e2e/test_harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import * as test from "#erdstall/test";
import {
PerunArt__factory,
PerunToken__factory,
} from "#erdstall/ledger/backend/contracts";
} from "#erdstall/ledger/backend/ethereum/contracts";
import { withTimeout } from "#erdstall/utils";

import { ethers, utils } from "ethers";
Expand Down Expand Up @@ -91,9 +91,9 @@ export function endToEndTestHarness(sdkActions: SDKActions) {
});
after(async () => erdstallProcessTerminate);

const sessions: Session[] = [];
const sessions: Session<["ethereum", "substrate"]>[] = [];
const forSessionsDo = async <R>(
action: (client: Session) => Promise<R>,
action: (client: Session<["ethereum", "substrate"]>) => Promise<R>,
range: { from?: number; upto?: number } = {},
) => {
return Promise.all(
Expand Down
8 changes: 8 additions & 0 deletions src/ledger/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ import { jsonObject } from "#erdstall/export/typedjson";
import { equalArray } from "#erdstall/utils/arrays";
import { ABIValue, customJSON } from "#erdstall/api/util";

// // Map key
// TODO: Substrate uses Pallets, we do not have an address for each pallet?
// type AddrKey struct {
// Type string `json:"type"` // addr.Type()
// Key string `json:"key"` // addr.Key()
// }
// TODO: Switch over type, parse key as expected by backends.

/**
* This class implements an address representation and is used within the SDK
* wherever an address is required.
Expand Down
4 changes: 2 additions & 2 deletions src/ledger/assets/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ABIValue, customJSON } from "#erdstall/api/util";
import { ErdstallToken } from "#erdstall/api/responses";
import { Address, addressKey } from "#erdstall/ledger";
import { TokenProvider } from "#erdstall/ledger/backend";
import { Erdstall } from "#erdstall/ledger/backend/contracts";
import { Erdstall } from "#erdstall/ledger/backend/ethereum/contracts";
import { decodePackedAmount } from "./amount";
import { Tokens, decodePackedIds } from "./tokens";
import { TokenType } from "./asset";
Expand Down Expand Up @@ -160,7 +160,7 @@ function isProperSubset(

export async function decodePackedAssets(
erdstall: Erdstall,
tokenProvider: Pick<TokenProvider, "tokenTypeOf">,
tokenProvider: Pick<TokenProvider<"ethereum">, "tokenTypeOf">,
values: [string, string][],
): Promise<Assets> {
const assets = new Assets();
Expand Down
11 changes: 5 additions & 6 deletions src/ledger/backend/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// SPDX-License-Identifier: Apache-2.0
"use strict";

export * from "./readconn";
export * from "./writeconn";
export * from "./contracts";
export * from "./contracts_deposit";
export * from "./tokencache";
export * from "./tokenmanager";
export * from "./tokenprovider";
export * from "./backends";
export * from "./metadata";
export * from "./reader";
export * from "./writer";
export * from "./signer";
2 changes: 1 addition & 1 deletion src/ledger/backend/metadata.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Client, ErdstallClient } from "#erdstall";
import { ClientConfig } from "#erdstall/api/responses";
import { Enclave } from "#erdstall/enclave";
import { Address } from "#erdstall/ledger";
import { PerunArt__factory } from "#erdstall/ledger/backend/contracts";
import { PerunArt__factory } from "#erdstall/ledger/backend/ethereum/contracts";
import * as test from "#erdstall/test";
import { Environment, setupEnv, PERUNART_URI } from "#erdstall/test/ledger";
import nock from "nock";
Expand Down
Loading

0 comments on commit 308e47a

Please sign in to comment.