Skip to content

Commit

Permalink
fix(connect): add init static function on ario class to create intera…
Browse files Browse the repository at this point in the history
…ction classes
  • Loading branch information
Atticus committed Apr 8, 2024
1 parent beb8610 commit f9c25e8
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 72 deletions.
8 changes: 3 additions & 5 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,14 @@ export type WalletAddress = string;

// TODO: append this with other configuration options (e.g. local vs. remote evaluation)
export type ContractSigner = ArweaveSigner | ArconnectSigner;
export type ContractConfiguration = {
signer?: ContractSigner; // TODO: optionally allow JWK in place of signer
} & (
export type WithSigner = { signer: ContractSigner }; // TODO: optionally allow JWK in place of signer
export type ContractConfiguration =
| {
contract?: WarpContract<unknown> | RemoteContract<unknown>;
}
| {
contractTxId: string;
}
);
};

export function isContractConfiguration<T>(
config: ContractConfiguration,
Expand Down
101 changes: 61 additions & 40 deletions src/common/ar-io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,76 @@ import {
RegistrationType,
UpdateGatewaySettingsParams,
WeightedObserver,
WithSigner,
WriteInteractionResult,
isContractConfiguration,
isContractTxIdConfiguration,
} from '../types.js';
import { mixInto } from '../utils/common.js';
import { RemoteContract } from './contracts/remote-contract.js';
import { InvalidSignerError, WarpContract } from './index.js';
import { WarpContract } from './index.js';

export class ArIO implements ArIOReadContract {
private contract: RemoteContract<ArIOState> | WarpContract<ArIOState>;
private signer: ContractSigner | undefined;
export class ArIO {
static createContract(
config: ContractConfiguration,
): WarpContract<ArIOState> {
if (isContractConfiguration<ArIOState>(config)) {
if (config.contract instanceof WarpContract) {
return config.contract;
} else {
// TODO: throw error if contract is not of WarpContract type
return new WarpContract<ArIOState>(config.contract.configuration());
}
} else if (isContractTxIdConfiguration(config)) {
return new WarpContract<ArIOState>({ contractTxId: config.contractTxId });
} else {
throw new Error('Invalid configuration.');
}
}

/**
* Initializes an ArIO instance.
*
* There are two overloads for this function:
* 1. When a signer is provided in the configuration, it returns an instance of ArIOWritable.
* 2. When a signer is not provided in the configuration, it returns an instance of ArIOReadable.
*
*
* @param {ContractConfiguration & WithSigner} config - The configuration object.
* If a signer is provided, it should be an object that implements the ContractSigner interface.
*
* @returns {ArIOWritable | ArIOReadable} - An instance of ArIOWritable if a signer is provided, otherwise an instance of ArIOReadable.
* @throws {Error} - Throws an error if the configuration is invalid.
*
* @example
* // Overload 1: When signer is provided
* const writable = ArIO.init({ signer: mySigner, contract: myContract });
*
* // Overload 2: When signer is not provided
* const readable = ArIO.init({ contract: myContract });
*/
static init(config: ContractConfiguration & WithSigner): ArIOWritable;
static init(config: ContractConfiguration): ArIOReadable;
static init(config: ContractConfiguration & { signer?: ContractSigner }) {
if (config.signer) {
const signer = config.signer;
const contract = this.createContract(config);
return new ArIOWritable({ signer, contract });
} else {
return new ArIOReadable(config);
}
}
}

export class ArIOReadable implements ArIOReadContract {
protected contract: RemoteContract<ArIOState> | WarpContract<ArIOState>;

constructor(
{ signer, ...config }: ContractConfiguration = {
config: ContractConfiguration = {
contract: new RemoteContract<ArIOState>({
contractTxId: ARNS_TESTNET_REGISTRY_TX,
}),
},
) {
this.signer = signer;

if (isContractConfiguration<ArIOState>(config)) {
this.contract = config.contract;
} else if (isContractTxIdConfiguration(config)) {
Expand All @@ -65,10 +114,6 @@ export class ArIO implements ArIOReadContract {
}
}

connected(): boolean {
return this.signer !== undefined;
}

/**
* Returns the current state of the contract.
*/
Expand Down Expand Up @@ -243,42 +288,18 @@ export class ArIO implements ArIOReadContract {

return auctions;
}

connect(signer: ContractSigner): void {
let writeableContract: WarpContract<ArIOState> | undefined = undefined;

// create or set the writable contract to be used in our mixin class
if (this.contract instanceof RemoteContract) {
writeableContract = new WarpContract(this.contract.configuration());
} else if (this.contract instanceof WarpContract) {
writeableContract = this.contract;
}

if (!writeableContract) {
throw new InvalidSignerError();
}

mixInto(
this.contract,
new ArIOWritable({
contract: writeableContract,
signer,
}),
);
}
}

export class ArIOWritable implements ArIOWriteContract {
private contract: WarpContract<ArIOState>;
export class ArIOWritable extends ArIOReadable implements ArIOWriteContract {
protected declare contract: WarpContract<ArIOState>;
private signer: ContractSigner;
constructor({
contract,
signer,
}: {
contract: WarpContract<ArIOState>;
signer: ContractSigner;
}) {
this.contract = contract;
} & WithSigner) {
super({ contract });
this.signer = signer;
}

Expand Down
23 changes: 0 additions & 23 deletions src/utils/common.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,3 @@
export * from './arweave.js';
export * from './http-client.js';
export * from './smartweave.js';
export * from './common.js';
6 changes: 3 additions & 3 deletions tests/integration/ar-io.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const contractTxId = ARNS_DEVNET_REGISTRY_TX;
const localCacheUrl = `https://api.arns.app`;
describe('ArIO Client', () => {
const signer = new ArweaveSigner(JSON.parse(process.env.PRIMARY_WALLET_JWK!));
const arIO = new ArIO({
const arIO = ArIO.init({
signer,
contract: new RemoteContract<ArIOState>({
cacheUrl: localCacheUrl,
Expand All @@ -30,13 +30,13 @@ describe('ArIO Client', () => {
});

it('should connect and return a valid instance', async () => {
const client = new ArIO({
const client = ArIO.init({
contract: new RemoteContract<ArIOState>({
contractTxId,
cacheUrl: localCacheUrl,
}),
});
expect(client.connect(signer)).toBeDefined();
expect(client).toBeDefined();
expect(client).toBeInstanceOf(ArIO);
});

Expand Down

0 comments on commit f9c25e8

Please sign in to comment.