Skip to content

Commit

Permalink
Merge pull request #186 from ar-io/PE-6573-add-data-signing-option
Browse files Browse the repository at this point in the history
feat(signing): add ao signer as option
  • Loading branch information
atticusofsparta authored Aug 20, 2024
2 parents 0fd3e46 + 1872a26 commit 9892451
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 191 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@
"axios-retry": "^4.3.0",
"eventemitter3": "^5.0.1",
"plimit-lit": "^3.0.1",
"winston": "^3.13.0"
"winston": "^3.13.0",
"zod": "^3.23.8"
},
"lint-staged": {
"**/*.{ts,js,mjs,cjs,md,json}": [
Expand Down
4 changes: 3 additions & 1 deletion src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import {
} from '@permaweb/aoconnect';
import { Signer } from 'arbundles';

import { AoSigner } from './token.js';

export type BlockHeight = number;
export type SortKey = string;
export type Timestamp = number;
Expand All @@ -33,7 +35,7 @@ export type TransactionId = string;
export type ProcessId = string;

// TODO: append this with other configuration options (e.g. local vs. remote evaluation)
export type ContractSigner = Signer | Window['arweaveWallet'];
export type ContractSigner = Signer | Window['arweaveWallet'] | AoSigner;
export type WithSigner<T = NonNullable<unknown>> = {
signer: ContractSigner;
} & T; // TODO: optionally allow JWK in place of signer
Expand Down
37 changes: 37 additions & 0 deletions src/utils/ao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
import { connect, createDataItemSigner } from '@permaweb/aoconnect';
import { createData } from 'arbundles';
import { z } from 'zod';

import { defaultArweave } from '../common/arweave.js';
import { AOProcess } from '../common/index.js';
Expand Down Expand Up @@ -157,7 +158,43 @@ export async function evolveANT({
return id;
}

export function isAoSigner(value: unknown): value is AoSigner {
const TagSchema = z.object({
name: z.string(),
value: z.union([z.string(), z.number()]),
});

const AoSignerSchema = z
.function()
.args(
z.object({
data: z.union([z.string(), z.instanceof(Buffer)]),
tags: z.array(TagSchema).optional(),
target: z.string().optional(),
anchor: z.string().optional(),
}),
)
.returns(
z.promise(
z.object({
id: z.string(),
raw: z.instanceof(ArrayBuffer),
}),
),
);
try {
AoSignerSchema.parse(value);
return true;
} catch {
return false;
}
}

export function createAoSigner(signer: ContractSigner): AoSigner {
if (isAoSigner(signer)) {
return signer;
}

if (!('publicKey' in signer)) {
return createDataItemSigner(signer) as AoSigner;
}
Expand Down
54 changes: 52 additions & 2 deletions tests/e2e/cjs/index.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
const { describe, it } = require('node:test');
const { describe, it, before } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
/**
* Ensure that npm link has been ran prior to running these tests
* (simply running npm run test:integration will ensure npm link is ran)
*/
const { IO, ioDevnetProcessId, ANTRegistry } = require('@ar.io/sdk');
const {
IO,
ioDevnetProcessId,
ANTRegistry,
ANT,
createAoSigner,
ArweaveSigner,
IOWriteable,
AoANTWriteable,
AoANTRegistryWriteable,
} = require('@ar.io/sdk');

const testWalletJSON = fs.readFileSync('../test-wallet.json', {
encoding: 'utf-8',
});
const testWallet = JSON.parse(testWalletJSON);
const signers = [
new ArweaveSigner(testWallet),
createAoSigner(new ArweaveSigner(testWallet)),
];

const io = IO.init({
processId: ioDevnetProcessId,
Expand Down Expand Up @@ -265,6 +285,14 @@ describe('IO', async () => {
});
assert.ok(tokenCost);
});

it('should be able to create IOWriteable with valid signers', async () => {
for (const signer of signers) {
const io = IO.init({ signer });

assert(io instanceof IOWriteable);
}
});
});

describe('ANTRegistry', async () => {
Expand All @@ -276,4 +304,26 @@ describe('ANTRegistry', async () => {
assert(Array.isArray(affiliatedAnts.Owned));
assert(Array.isArray(affiliatedAnts.Controlled));
});

it('should be able to create AoANTRegistryWriteable with valid signers', async () => {
for (const signer of signers) {
const registry = ANTRegistry.init({
signer,
});
assert(registry instanceof AoANTRegistryWriteable);
}
});
});

describe('ANT', async () => {
it('should be able to create ANTWriteable with valid signers', async () => {
for (const signer of signers) {
const ant = ANT.init({
processId: 'aWI_dq1JH7facsulLuas1X3l5dkKuWtixcZDYMw9mpg',
signer,
});

assert(ant instanceof AoANTWriteable);
}
});
});
54 changes: 53 additions & 1 deletion tests/e2e/esm/index.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
import { ANTRegistry, IO, ioDevnetProcessId } from '@ar.io/sdk';
import {
ANT,
ANTRegistry,
AoANTRegistryWriteable,
AoANTWriteable,
ArweaveSigner,
IO,
IOWriteable,
createAoSigner,
ioDevnetProcessId,
} from '@ar.io/sdk';
import { strict as assert } from 'node:assert';
import fs from 'node:fs';
import { describe, it } from 'node:test';

const testWalletJSON = fs.readFileSync('../test-wallet.json', {
encoding: 'utf-8',
});

const testWallet = JSON.parse(testWalletJSON);
const signers = [
new ArweaveSigner(testWallet),
createAoSigner(new ArweaveSigner(testWallet)),
];

/**
* Ensure that npm link has been ran prior to running these tests
* (simply running npm run test:integration will ensure npm link is ran)
Expand All @@ -10,6 +31,7 @@ import { describe, it } from 'node:test';
const io = IO.init({
processId: ioDevnetProcessId,
});

describe('IO', async () => {
it('should be able to get the process information', async () => {
const epoch = await io.getInfo();
Expand Down Expand Up @@ -266,6 +288,14 @@ describe('IO', async () => {
});
assert.ok(tokenCost);
});

it('should be able to create IOWriteable with valid signers', async () => {
for (const signer of signers) {
const io = IO.init({ signer });

assert(io instanceof IOWriteable);
}
});
});

describe('ANTRegistry', async () => {
Expand All @@ -277,4 +307,26 @@ describe('ANTRegistry', async () => {
assert(Array.isArray(affiliatedAnts.Owned));
assert(Array.isArray(affiliatedAnts.Controlled));
});

it('should be able to create AoANTRegistryWriteable with valid signers', async () => {
for (const signer of signers) {
const registry = ANTRegistry.init({
signer,
});
assert(registry instanceof AoANTRegistryWriteable);
}
});
});

describe('ANT', async () => {
it('should be able to create ANTWriteable with valid signers', async () => {
for (const signer of signers) {
const ant = ANT.init({
processId: 'aWI_dq1JH7facsulLuas1X3l5dkKuWtixcZDYMw9mpg',
signer,
});

assert(ant instanceof AoANTWriteable);
}
});
});
11 changes: 11 additions & 0 deletions tests/e2e/test-wallet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"kty": "RSA",
"n": "s-Whr7NsoyY0x5nFZDAXIzLymEQvK-9ZW_-cH7TKfnxJn24Z9KndUl8fuE_7QRP2VUmlcTM-YjeS7maw68CZrk_2VKbxnN1Gcvj1SqfuvdnZ0aDgD-FQVEpnOWtAToAEZrV-mwiXBHGEIr8_ntmw4TZJwXmNjVUEhA4rVekKDGHD2k-mooc1wliNG-WMS5e-6Qbor_WNbI0G7HI1WJ46qgMZr4aK2OV1WkwL7Z-5xtSUKLJJJ9Uw1BJvjxaOPo3Eu6zJGxnTGMt3xKSD4ZnJV5H16W9609OTURLezVoIQ8VxmF5W_2sawueAp3g2x4dAwaBIhrfQVjn-Fq7bpTKFg1tlfuzIruh0KUXqftYfWpD3qJxHZLnUJl90oCLUw5oDs7Fvx23TToy92ouZdeMhHjIkNRDBGMAuOzrE5qz-f973LDR0Hz88wzBZ7mZDvSA_UEPKVoRZ99ON_w79BU-Pw1XlvYRAAEDrC1zWojVxMGCqRaWR4OMbQE5eWGTE-5tlpb2zuc970ihdwEmS54V6SLzx9mVAy6WfgWMLxYyqjz30538D8ZbUn8mGk4-WVoaXgncPU2F9bVs3bNaTuAWZZxAPZ7E139NTIrW-MbH_nTgch09vq7giI8XEWryWzRSGmZl-IoRN4Nnn2FyoX8nuk7QyZC2j-6y5j4jWXvkJABE",
"e": "AQAB",
"d": "PE0s9YhfUhDsgDu7Puof11yslP3GEiQZAA2ed8JSXjOrOhXd_XUzCvl32IB26EmYuN4G5vsWXjXiuqcRhvT4jsWe_KE5PCuwAboR_wRrspfju7EBalFMa_TExSp-U9H1p7gOyEkI1iR29m7FFKpD8DoSXxgvqsBk0x8sx49mHuBmljc81B4elxa3tjIr5Orow5PdS54z2b8sIvXli97-Kx7-7SdcQ3gm7i2vkeeIjm2TfFDG1ONRisTjQEN_StiaqY4xmzP83sLVUsUSr_ys0P3MQINt2LODHhoFNTCItK7qdPiqkNOGFO8k4P4a3qcnvb_Mj9vtqfmmglP6rFVTCzPHWSSZi2HOZlPGQc53Zx33ZS4moNNTo63hwsa4VKqWTNvZoZF9MafuBQYn_GovkaJkKB542VnhGoT-NsA3HISDhffT6U0q-vWqUOIZmgf8Ut3ghS9XiFUjnBn_EdDix_ryxnmrwpWwUk4q15gDCJ-Ych05uzUbtNPk0LdLRPofpcOJ0uPSv9-5r6ouYJoR92ODxXFhcWGq6GFVT9s9ETNMehw8A54J72n5XfnePF8D5qPe4YZw8DgcIAzmrr42jmNI5YSt3lBVfOoe8meYc_a77t0WmTsIia9nnBpgP4dl12s6EAentsFZfvLRU3cvCy1gsk2En3vPMdiRXJUzrkE",
"p": "9nbx4FZClWKyHFygc3djqRyKff44KD7KFMgOSEKbxvioop1lynSLjTsRMMzT31_htXq0COSLBrUmbzoI5iO8GUmU9F_ht1j4sbwcsYmyyLdNsURWZwYCb00LPDyqvqn87J5IuTifJ4CZB8e1EE3H8HrbnB-uKZJGiEhaIiCCs1-t0sGKY9QtuE2Ovly9RGkj6fi9yqIZyF6ySHopWtLQ90GtVh8El4eIL-PeGPBvahbffUNOwEpfc0QIjOBkrHT8wdlXuU3rWFSi7aKd2mVj6QFiq_pF-Z8ESc0NAQlLIY0kbKKv29blcpY9sgKBpTAYMYRj93AdQstNoddRZ5fdyw",
"q": "utth1reY8OFEDIHe48K_pyyPmoMsRCdFhtXEqBljRNaQKQk6ijajPco7ycYTucef1_TlIBbSfm6WropbRyi9e9ebaA0kWNqPYaef9vtYEwdq3f9YfrHXaVXSGmfWXw-fp81QGm6IDRN3YlRn-_6rWB7MynkvYdJSh7K_GRw39TUkcWIrKNbFmPi1InKi-i9VDTQJL1REkQmAduPScjRzsNGmM3Ngqt3PNfejhronSICSGrwbUJ9-C5sauGAIJo090KS2f8p15ljGQ_X0WT9JWnsZ59K8nL5cLOUVZpKc5U0AoS_HqR7O7BIFLJo8BEWiJd_Jmg-Ln6UCOzxWBZleEw",
"dp": "47PYm66WLXXVoCZjhsoSpTbdLLImJ-h6wuBhcZk4Wod5JWPNm1I5a-3aX_-c746h9Qy8MEsVtsi-DZzMg_MX4TT-DRhYbRAiE_L7f3r8Vjwj51Z_jQccUMAZVTmndieOqP1DqvwI7nH88BctzTZPNnoLUx5hxb6Cs35E56qplhcbfM-aj8iDxPbCnlUH96A7sfpBPmis8VWr2RIkCukibo2bGynlECoDRFt94gSgqp8fM5dvtm__53o_fAgEeuBKdL3cMjMu75iiPnIy7Icn2ymQg9rhs1GaoKR1EzQG2aSQtl1HpA_SRB9SOJfgN0FL2NO7l-tY3VD_FDrd1puUKQ",
"dq": "t3YSl9jnpwnl4Ena59EcjyznShOkcL4GO57DWTCkEMCCBmhzO6TtngtjrHZ4g52GSWi_VkRSI6S8-V4KxNExSdilUwIkP8FHqeAE5WBeV0CfIpxE7Q_7qgaDJT3ycp9KaFzjWzBPEFeejcLF3dtrrDeBZwKZDPiN44ISsrrMDktBHrn-GjjVBZ6badkYP4Adh7shkYCxWZ30rcZ9p3fsZx1Qi4-qx9jES_56Zht72mmyCeHLB9uwzABbuc8_8WoX2TT_onTMUX-0GqHwaXgDs3zOMJjuaw9UPRgnbPBib5itF5Vr-ZawH4SJ5AMDDka4L2uL62F7-yDuEe7pntG4VQ",
"qi": "PYzb643Ko2kHMwP7z44xAoldwzvKfKy-5rKjifzpJ-oX3Nsec99goV5JfDXDDmZhJmfqX93L9znEIFmA17dwzwJ6Gho2ReqDacze-SQNyKywuE77b5XXvCx-lVx1DWS0DTR7ykUkf8K6Pl6JKHNpc0FAeK8olk0PdqVf-TvXE8NjHc1vDsxwK2woiUkizyd-Xn054U1Abe_sy7_gwFFCNo7nUFJxk6AG4v4yinbxn8dAmAATh37sPnB3U4Ac4yNfFYSqf6HZzCMyt2UlPZsLKLZP2OtHoYaHWJWoZjfyChbaEleXTvaDIGzrgrnsOH5fsCvGie1zZAs1X7DhvCiTTQ"
}
Loading

0 comments on commit 9892451

Please sign in to comment.