This repository has been archived by the owner on Jun 17, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
arweave-storage.ts
167 lines (151 loc) · 5.67 KB
/
arweave-storage.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import Arweave from 'arweave/node';
import Transaction from 'arweave/node/lib/transaction';
import { JWKInterface } from 'arweave/node/lib/wallet';
import { AxiosResponse } from "axios";
import { and, equals } from 'arql-ops';
export interface IArweaveStorage {
arweave: Arweave;
runQuery(query: object): Promise<string[]>;
getTransaction(id: string): Promise<Transaction>;
getTransactionData(id: string, isString: boolean): Promise<string | Uint8Array>;
sendTransaction(transaction: Transaction): Promise<AxiosResponse<any>>;
createDataTransaction(type: string, data: string | Uint8Array, pkgName: string, fileName: string, tags?: string[][]): Promise<Transaction>
getPackageTxByFileName(name: string, fileName: string, fromAddress: string|undefined): Promise<string[]>;
getPackageTxByFileNameAndVersion(name: string, fileName: string, pkgVersion:string, fromAddress?: string): Promise<string[]>
getAllPackagesHashes(fromAddress?: string): Promise<string[]>;
}
export const env = 'TEST-6';
export const source = 'NPM';
export default class ArweaveStorage implements IArweaveStorage {
public arweave: Arweave;
public jwk: JWKInterface|undefined;
public constructor(arweave: Arweave, jwk: string|undefined) {
this.arweave = arweave;
this.jwk = undefined;
if(jwk) {
this.jwk = JSON.parse(jwk);
}
}
public async runQuery(query: Object): Promise<string[]> {
const result = await this.arweave.arql(query);
return result;
}
public async getTransaction(id: string): Promise<Transaction> {
const result = await this.arweave.transactions.get(id);
//Validate transaction integrity
const isValid = await this.arweave.transactions.verify(result);
if(!isValid) {
throw new Error(
`Invalid transaction signature! The transaction data does not match the signature.`
);
}
return result;
}
public async getTransactionData(id: string, isString: boolean): Promise<string | Uint8Array> {
const result = await this.arweave.transactions.getData(id, {decode:true, string: isString});
return result;
}
private delay(ms: number) {
return new Promise( resolve => setTimeout(resolve, ms) );
}
public async sendTransaction(transaction: Transaction): Promise<AxiosResponse<any>> {
return new Promise(async (resolve,reject) => {
const result = await this.arweave.transactions.post(transaction);
if(result.status = 200) {
console.log('Delay', Number(transaction.data_size)/10000+1000);
await this.delay(Number(transaction.data_size)/10000+1000);
// let response = await this.arweave.transactions.getStatus(transaction.id);
// while(response.status == 202) {
// await this.delay(2000);
// response = await this.arweave.transactions.getStatus(transaction.id);
// }
// if(response.status > 202) {
// reject(response);
// }
resolve(result);
} else {
reject(result);
}
});
}
public async createDataTransaction(type: string, data: string | Uint8Array, pkgName: string, fileName: string, tags?: string[][]): Promise<Transaction> {
if(!this.jwk)
throw new Error('Undefined JWK, cant create a transaction without it');
let transaction = await this.arweave.createTransaction({ data }, this.jwk);
let defaultTags = [['Content-Type', type], ['App-Name','verdaccio-arweave'], ['App-Version','0.0.1'],['Source', source],
['ENV', env], ['Package-Name', pkgName], ['File-Name', fileName] ]
for (const tag of defaultTags) {
transaction.addTag(tag[0], tag[1]);
}
if(tags){
for (const tag of tags) {
transaction.addTag(tag[0], tag[1]);
}
}
await this.arweave.transactions.sign(transaction, this.jwk);
return transaction;
}
public async getPackageTxByFileName(name: string, fileName: string, fromAddress?: string): Promise<string[]> {
let myQuery = and(
equals('to', ''),
equals('Source', source),
equals('ENV', env),
equals('Package-Name', name),
equals('File-Name', fileName),
);
if(fromAddress) {
myQuery = and(
equals('from', fromAddress),
equals('to', ''),
equals('Source', source),
equals('ENV', env),
equals('Package-Name', name),
equals('File-Name', fileName),
);
}
const result = await this.runQuery(myQuery);
return result;
}
public async getPackageTxByFileNameAndVersion(name: string, fileName: string, pkgVersion:string, fromAddress?: string): Promise<string[]> {
let myQuery = and(
equals('to', ''),
equals('Source', source),
equals('ENV', env),
equals('Package-Name', name),
equals('Package-Version', pkgVersion),
equals('File-Name', fileName),
);
if(fromAddress) {
myQuery = and(
equals('from', fromAddress),
equals('to', ''),
equals('Source', source),
equals('ENV', env),
equals('Package-Name', name),
equals('Package-Version', pkgVersion),
equals('File-Name', fileName),
);
}
const result = await this.runQuery(myQuery);
return result;
}
public async getAllPackagesHashes(fromAddress?: string): Promise<string[]> {
let myQuery = and(
equals('to', ''),
equals('Source', source),
equals('ENV', env),
equals('File-Name', 'package.json'),
);
if(fromAddress) {
myQuery = and(
equals('from', fromAddress),
equals('to', ''),
equals('Source', source),
equals('ENV', env),
equals('File-Name', 'package.json'),
);
}
const txHashList = await this.runQuery(myQuery);
return txHashList;
}
}