Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
599 changes: 499 additions & 100 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,6 @@
"dependencies": {
"@tableland/evm": "^4.2.2",
"@tableland/sqlparser": "^1.0.6-pre.5",
"ethers": "^5.7.2"
"ethers": "^6.3.0"
}
}
33 changes: 18 additions & 15 deletions src/helpers/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type WaitableTransactionReceipt } from "../registry/utils.js";
import { type ChainName, getBaseUrl } from "./chains.js";
import { type Signer, type ExternalProvider, getSigner } from "./ethers.js";
import { type Signer, type Eip1193Provider, getSigner } from "./ethers.js";

export interface ReadConfig {
baseUrl: string;
Expand Down Expand Up @@ -31,24 +31,23 @@ export async function extractBaseUrl(
conn: Config = {},
chainNameOrId?: ChainName | number
): Promise<string> {
if (conn.baseUrl == null) {
if (conn.signer == null) {
if (chainNameOrId == null) {
throw new Error(
"missing connection information: baseUrl, signer, or chainId required"
);
}
return getBaseUrl(chainNameOrId);
}
if (conn.baseUrl != null) return conn.baseUrl;
if (conn.signer != null) {
const chainId = await conn.signer.getChainId();
return getBaseUrl(chainId);
}
return conn.baseUrl;
if (chainNameOrId != null) {
return getBaseUrl(chainNameOrId);
}

throw new Error(
"missing connection information: baseUrl, signer, or chainId required"
);
}

export async function extractSigner(
conn: Config = {},
external?: ExternalProvider
external?: Eip1193Provider
): Promise<Signer> {
if (conn.signer == null) {
return await getSigner(external);
Expand All @@ -58,14 +57,18 @@ export async function extractSigner(

export async function extractChainId(conn: Config = {}): Promise<number> {
const signer = await extractSigner(conn);
const chainId = await signer.getChainId();
const network = await signer.provider?.getNetwork();

if (chainId === 0 || isNaN(chainId) || chainId == null) {
if (
network == null ||
network.chainId === BigInt("0") ||
network.chainId == null
) {
/* c8 ignore next 4 */
throw new Error(
"cannot find chainId: is your signer connected to a network?"
);
}

return chainId;
return Number(network.chainId);
}
63 changes: 37 additions & 26 deletions src/helpers/ethers.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import {
providers,
getDefaultProvider,
BrowserProvider,
EventLog,
type Eip1193Provider,
type ContractTransactionResponse,
type ContractTransactionReceipt,
type Signer,
type Overrides,
type ContractTransaction,
type ContractReceipt,
} from "ethers";
import { type TransactionReceipt } from "../validator/receipt.js";
import { type SignerConfig } from "./config.js";

type ExternalProvider = providers.ExternalProvider;
const { getDefaultProvider, Web3Provider } = providers;

// eslint-disable-next-line @typescript-eslint/no-namespace
declare module globalThis {
// eslint-disable-next-line no-var
var ethereum: ExternalProvider | undefined;
var ethereum: Eip1193Provider | undefined;
}

/**
Expand All @@ -29,11 +29,13 @@ export async function getOverrides({
const opts: Overrides = {};
const network = await signer.provider?.getNetwork();
/* c8 ignore next 7 */
if (network?.chainId === 137) {
const feeData = await signer.getFeeData();
if (feeData.gasPrice != null) {
if (network?.chainId === BigInt("137")) {
const feeData = await signer.provider?.getFeeData();
if (feeData?.gasPrice != null) {
opts.gasPrice =
Math.floor(feeData.gasPrice.toNumber() * 1.1) ?? undefined;
// NOTE: There's no guarantee `feeData.gasPrice` is a JS safe integer which means
// this might not be accurate, but it's just an estimate so this is probably ok
Math.floor(Number(feeData.gasPrice) * 1.1) ?? undefined;
}
}
return opts;
Expand Down Expand Up @@ -73,20 +75,29 @@ export interface MultiEventTransactionReceipt {
*
*/
export async function getContractReceipt(
tx: ContractTransaction
tx: ContractTransactionResponse
): Promise<MultiEventTransactionReceipt> {
const receipt = await tx.wait();

if (receipt == null) {
throw new Error(
`could not get receipt for transaction: ${JSON.stringify(tx, null, 4)}`
);
}

/* c8 ignore next */
const events = receipt.events ?? [];
const transactionHash = receipt.transactionHash;
const logs = receipt.logs ?? [];
const transactionHash = receipt.hash;
const blockNumber = receipt.blockNumber;
const chainId = tx.chainId;
// NOTE: chainId is always a JS safe integer
const chainId = Number(tx.chainId);
const tableIds: string[] = [];
for (const event of events) {
const tableId =
event.args?.tableId != null && event.args.tableId.toString();
switch (event.event) {
for (const log of logs) {
if (!(log instanceof EventLog)) continue;

const tableId = log.args?.tableId != null && log.args.tableId.toString();

switch (log.eventName) {
case "CreateTable":
case "RunSQL":
if (tableId != null) tableIds.push(tableId);
Expand All @@ -105,7 +116,7 @@ export async function getContractReceipt(
* @returns A promise that resolves to a valid web3 provider/signer
* @throws If no global ethereum object is available.
*/
export async function getSigner(external?: ExternalProvider): Promise<Signer> {
export async function getSigner(external?: Eip1193Provider): Promise<Signer> {
const provider = external ?? globalThis.ethereum;
if (provider == null) {
throw new Error("provider error: missing global ethereum provider");
Expand All @@ -116,14 +127,14 @@ export async function getSigner(external?: ExternalProvider): Promise<Signer> {
);
}
await provider.request({ method: "eth_requestAccounts" });
const web3Provider = new Web3Provider(provider);
return web3Provider.getSigner();
const web3Provider = new BrowserProvider(provider);
return await web3Provider.getSigner();
}

export {
Signer,
getDefaultProvider,
type ExternalProvider,
type ContractTransaction,
type ContractReceipt,
type Signer,
type ContractTransactionResponse,
type ContractTransactionReceipt,
type Eip1193Provider,
};
6 changes: 3 additions & 3 deletions src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ export {
} from "./config.js";
export {
type Signer,
type ExternalProvider,
type Eip1193Provider,
getDefaultProvider,
type ContractTransaction,
type ContractReceipt,
type ContractTransactionResponse,
type ContractTransactionReceipt,
type RegistryReceipt,
type MultiEventTransactionReceipt,
getSigner,
Expand Down
3 changes: 2 additions & 1 deletion src/lowlevel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
type Config,
extractBaseUrl,
extractChainId,
extractSigner,
type Signal,
type ReadConfig,
Expand Down Expand Up @@ -78,7 +79,7 @@ export async function exec(
{ type, sql, tables: [first] }: ExtractedStatement
): Promise<WaitableTransactionReceipt> {
const signer = await extractSigner(config);
const chainId = await signer.getChainId();
const chainId = await extractChainId(config);
const baseUrl = await extractBaseUrl(config, chainId);
const _config = { baseUrl, signer };
const _params = { chainId, first, statement: sql };
Expand Down
22 changes: 16 additions & 6 deletions src/registry/controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Typed } from "ethers";
import { type SignerConfig } from "../helpers/config.js";
import { type ContractTransaction } from "../helpers/ethers.js";
import { type ContractTransactionResponse } from "../helpers/ethers.js";
import { type TableIdentifier, getContractSetup } from "./contract.js";

export interface SetParams {
Expand All @@ -16,26 +17,35 @@ export interface SetParams {
export async function setController(
{ signer }: SignerConfig,
params: SetParams
): Promise<ContractTransaction> {
): Promise<ContractTransactionResponse> {
const { contract, overrides, tableId } = await getContractSetup(
signer,
params.tableName
);
const caller = await signer.getAddress();
const controller = params.controller;
return await contract.setController(caller, tableId, controller, overrides);
return await contract.setController(
Typed.address(caller),
Typed.uint256(tableId),
Typed.address(controller),
overrides
);
}

export async function lockController(
{ signer }: SignerConfig,
tableName: string | TableIdentifier
): Promise<ContractTransaction> {
): Promise<ContractTransactionResponse> {
const { contract, overrides, tableId } = await getContractSetup(
signer,
tableName
);
const caller = await signer.getAddress();
return await contract.lockController(caller, tableId, overrides);
return await contract.lockController(
Typed.address(caller),
Typed.uint256(tableId),
overrides
);
}

export async function getController(
Expand All @@ -46,5 +56,5 @@ export async function getController(
signer,
tableName
);
return await contract.getController(tableId, overrides);
return await contract.getController(Typed.uint256(tableId), overrides);
}
23 changes: 14 additions & 9 deletions src/registry/create.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Typed } from "ethers";
import { normalize } from "../helpers/index.js";
import { type SignerConfig } from "../helpers/config.js";
import { type ContractTransaction } from "../helpers/ethers.js";
import { type ContractTransactionResponse } from "../helpers/ethers.js";
import { validateTableName } from "../helpers/parser.js";
import { getContractAndOverrides } from "./contract.js";

Expand Down Expand Up @@ -84,14 +85,14 @@ export type CreateParams = CreateOneParams | CreateManyParams;
export async function createTable(
config: SignerConfig,
params: CreateOneParams
): Promise<ContractTransaction> {
): Promise<ContractTransactionResponse> {
return await _createOne(config, params);
}

export async function create(
config: SignerConfig,
params: CreateParams
): Promise<ContractTransaction> {
): Promise<ContractTransactionResponse> {
if (isCreateOne(params)) {
return await _createOne(config, params);
}
Expand All @@ -101,27 +102,31 @@ export async function create(
async function _createOne(
{ signer }: SignerConfig,
{ statement, chainId }: CreateOneParams
): Promise<ContractTransaction> {
): Promise<ContractTransactionResponse> {
const owner = await signer.getAddress();
const { contract, overrides } = await getContractAndOverrides(
signer,
chainId
);
return await contract["create(address,string)"](owner, statement, overrides);
return await contract.create(
Typed.address(owner),
Typed.statement(statement),
overrides
);
}

async function _createMany(
{ signer }: SignerConfig,
{ statements, chainId }: CreateManyParams
): Promise<ContractTransaction> {
): Promise<ContractTransactionResponse> {
const owner = await signer.getAddress();
const { contract, overrides } = await getContractAndOverrides(
signer,
chainId
);
return await contract["create(address,string[])"](
owner,
statements,
return await contract.create(
Typed.address(owner),
Typed.array(statements.map((stmt) => Typed.string(stmt))),
overrides
);
}
Expand Down
Loading