Skip to content

Commit

Permalink
feat(signer): add arweave signer to ario class
Browse files Browse the repository at this point in the history
  • Loading branch information
Atticus committed Mar 16, 2024
1 parent e0c6fca commit 7e08097
Show file tree
Hide file tree
Showing 8 changed files with 696 additions and 32 deletions.
6 changes: 5 additions & 1 deletion examples/node/index.cjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
const Arweave = require('arweave');
const {
ArIO,
ARNS_TESTNET_REGISTRY_TX,
} = require('../../lib/cjs/node/index.js');
const { ArweaveSigner } = require('arbundles');

(async () => {
const arIO = new ArIO();
const jwk = await Arweave.init({}).wallets.generate();
const signer = new ArweaveSigner(jwk);
const arIO = new ArIO({ signer });
// testnet gateways
const testnetGateways = await arIO.getGateways();
const protocolBalance = await arIO.getBalance({
Expand Down
7 changes: 6 additions & 1 deletion examples/node/index.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { ArweaveSigner } from 'arbundles';
import Arweave from 'arweave';

import { ARNS_TESTNET_REGISTRY_TX, ArIO } from '../../lib/esm/node/index.js';

(async () => {
const arIO = new ArIO();
const jwk = await Arweave.init({}).wallets.generate();
const signer = new ArweaveSigner(jwk);
const arIO = new ArIO({ signer });
// testnet gateways
const testnetGateways = await arIO.getGateways();
const protocolBalance = await arIO.getBalance({
Expand Down
6 changes: 4 additions & 2 deletions examples/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,12 @@ <h1 class="text-textPrimary w-full font-bold">View Distribution Data</h1>
</div>

<script type="module">
import Arweave from 'https://unpkg.com/arweave/bundles/web.bundle.js';

import { ArIO } from './web.bundle.min.js';

// set up our client
const arIO = new ArIO();
const jwk = await Arweave.init({}).wallets.generate();
const arIO = new ArIO({ signer: jwk });

// fetch data on page load
async function init() {
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,11 @@
"typescript": "^5.1.6"
},
"dependencies": {
"arbundles": "^0.11.0",
"arweave": "^1.14.4",
"axios": "1.4.0",
"setimmediate": "^1.0.5",
"warp-contracts": "^1.4.38",
"winston": "^3.11.0",
"setimmediate": "^1.0.5"
"winston": "^3.11.0"
}
}
47 changes: 33 additions & 14 deletions src/common/ar-io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { ArconnectSigner, ArweaveSigner } from 'arbundles/web';
import { JWKInterface } from 'arweave/node/lib/wallet.js';

import { ARNS_TESTNET_REGISTRY_TX } from '../constants.js';
import {
ArIOContract,
Expand All @@ -29,6 +32,7 @@ import {
SmartWeaveContract,
WeightedObserver,
} from '../types.js';
import { isJwk } from '../utils/arweave.js';
import { RemoteContract } from './contracts/remote-contract.js';

// TODO: append this with other configuration options (e.g. local vs. remote evaluation)
Expand All @@ -54,21 +58,36 @@ function isContractTxIdConfiguration(

export class ArIO implements ArIOContract {
private contract: SmartWeaveContract<ArIOState>;
signer: ArweaveSigner | ArconnectSigner | JWKInterface;

constructor(
config: ContractConfiguration = {
// default to a contract that uses the arns service to do the evaluation
contract: new RemoteContract<ArIOState>({
contractTxId: ARNS_TESTNET_REGISTRY_TX,
}),
},
) {
if (isContractConfiguration<ArIOState>(config)) {
this.contract = config.contract;
} else if (isContractTxIdConfiguration(config)) {
this.contract = new RemoteContract<ArIOState>({
contractTxId: config.contractTxId,
});
constructor({
signer,
...config
}: ContractConfiguration & {
signer: ArweaveSigner | ArconnectSigner | JWKInterface;
}) {
this.signer = isJwk(signer) ? new ArweaveSigner(signer) : signer;

const isContract = isContractConfiguration<ArIOState>(config);
const isContractTxId = isContractTxIdConfiguration(config);
const isBoth = isContract && isContractTxId;
switch (true) {
case isBoth:
throw new Error(
'ArIO contract configuration must include either `contract` or `contractTxId`, but not both',
);
case isContract:
this.contract = config.contract;
return;
case isContractTxId:
this.contract = new RemoteContract<ArIOState>({
contractTxId: config.contractTxId,
});
return;
default:
this.contract = new RemoteContract<ArIOState>({
contractTxId: ARNS_TESTNET_REGISTRY_TX,
});
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/utils/arweave.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { b64UrlToBuffer } from 'arweave/node/lib/utils.js';
import { JWKInterface } from 'arweave/node/lib/wallet.js';

import { BlockHeight } from '../common.js';
import { ARWEAVE_TX_REGEX } from '../constants.js';

Expand All @@ -24,3 +27,15 @@ export const validateArweaveId = (id: string): boolean => {
export function isBlockHeight(height: string | number): height is BlockHeight {
return height !== undefined && !isNaN(parseInt(height.toString()));
}

export const isJwk = (obj: object): obj is JWKInterface => {
let valid = true;
['n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi'].map(
(key) => !(key in obj) && (valid = false),
);
const bufferOfN = b64UrlToBuffer(obj['n']);
if (bufferOfN.length !== 512) {
valid = false;
}
return valid;
};
23 changes: 18 additions & 5 deletions tests/ar-io.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { ArweaveSigner } from 'arbundles';
import Arweave from 'arweave';

import { ArIO } from '../src/common/ar-io.js';
import { RemoteContract } from '../src/common/contracts/remote-contract.js';
import { ARNS_DEVNET_REGISTRY_TX } from '../src/constants.js';
Expand All @@ -11,11 +14,21 @@ const evaluateToSortKey = new SmartWeaveSortKey(
'000001376946,0000000000000,18d52956c8e13ae1f557b4e67f6f298b8ffd2a5cd96e42ec24ca649b7401510f',
);
describe('ArIO Client', () => {
const arIO = new ArIO({
contract: new RemoteContract<ArIOState>({
url: process.env.REMOTE_CACHE_URL || 'http://localhost:3000',
contractTxId: ARNS_DEVNET_REGISTRY_TX,
}),
let arIO: ArIO;
beforeAll(async () => {
const arweave = Arweave.init({
host: 'arweave.net',
protocol: 'https',
port: 443,
});
const jwk = await arweave.wallets.generate();
const signer = new ArweaveSigner(jwk);
arIO = new ArIO({
contract: new RemoteContract<ArIOState>({
contractTxId: ARNS_DEVNET_REGISTRY_TX,
}),
signer,
});
});
it('should create a custom ArIO client', () => {
expect(arIO).toBeInstanceOf(ArIO);
Expand Down

0 comments on commit 7e08097

Please sign in to comment.