ceramic-cacao
Advanced tools
Comparing version 0.0.9 to 0.0.10
@@ -1,2 +0,2 @@ | ||
import { apgApi, apgLib } from 'apg-js'; | ||
import apg from 'apg-js'; | ||
const GRAMMAR = ` | ||
@@ -151,4 +151,4 @@ sign-in-with-ethereum = | ||
export class ParsedMessage { | ||
constructor(msg){ | ||
const api = new apgApi(GRAMMAR); | ||
constructor(msg) { | ||
const api = new apg.apgApi(GRAMMAR); | ||
api.generate(); | ||
@@ -162,9 +162,9 @@ if (api.errors.length) { | ||
const grammarObj = api.toObject(); | ||
const parser = new apgLib.parser(); | ||
parser.ast = new apgLib.ast(); | ||
const id = apgLib.ids; | ||
const domain = function(state, chars, phraseIndex, phraseLength, data) { | ||
const parser = new apg.apgLib.parser(); | ||
parser.ast = new apg.apgLib.ast(); | ||
const id = apg.apgLib.ids; | ||
const domain = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
data.domain = apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
data.domain = apg.apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
} | ||
@@ -174,6 +174,6 @@ return ret; | ||
parser.ast.callbacks.domain = domain; | ||
const address = function(state, chars, phraseIndex, phraseLength, data) { | ||
const address = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
data.address = apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
data.address = apg.apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
} | ||
@@ -183,6 +183,6 @@ return ret; | ||
parser.ast.callbacks.address = address; | ||
const statement = function(state, chars, phraseIndex, phraseLength, data) { | ||
const statement = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
data.statement = apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
data.statement = apg.apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
} | ||
@@ -192,7 +192,7 @@ return ret; | ||
parser.ast.callbacks.statement = statement; | ||
const uri = function(state, chars, phraseIndex, phraseLength, data) { | ||
const uri = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
if (!data.uri) { | ||
data.uri = apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
data.uri = apg.apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
} | ||
@@ -203,6 +203,6 @@ } | ||
parser.ast.callbacks.uri = uri; | ||
const version = function(state, chars, phraseIndex, phraseLength, data) { | ||
const version = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
data.version = apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
data.version = apg.apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
} | ||
@@ -212,6 +212,6 @@ return ret; | ||
parser.ast.callbacks.version = version; | ||
const chainId = function(state, chars, phraseIndex, phraseLength, data) { | ||
const chainId = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
data.chainId = apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
data.chainId = apg.apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
} | ||
@@ -221,6 +221,6 @@ return ret; | ||
parser.ast.callbacks['chain-id'] = chainId; | ||
const nonce = function(state, chars, phraseIndex, phraseLength, data) { | ||
const nonce = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
data.nonce = apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
data.nonce = apg.apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
} | ||
@@ -230,6 +230,6 @@ return ret; | ||
parser.ast.callbacks.nonce = nonce; | ||
const issuedAt = function(state, chars, phraseIndex, phraseLength, data) { | ||
const issuedAt = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
data.issuedAt = apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
data.issuedAt = apg.apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
} | ||
@@ -239,6 +239,6 @@ return ret; | ||
parser.ast.callbacks['issued-at'] = issuedAt; | ||
const expirationTime = function(state, chars, phraseIndex, phraseLength, data) { | ||
const expirationTime = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
data.expirationTime = apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
data.expirationTime = apg.apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
} | ||
@@ -248,6 +248,6 @@ return ret; | ||
parser.ast.callbacks['expiration-time'] = expirationTime; | ||
const notBefore = function(state, chars, phraseIndex, phraseLength, data) { | ||
const notBefore = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
data.notBefore = apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
data.notBefore = apg.apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
} | ||
@@ -257,6 +257,6 @@ return ret; | ||
parser.ast.callbacks['not-before'] = notBefore; | ||
const requestId = function(state, chars, phraseIndex, phraseLength, data) { | ||
const requestId = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
data.requestId = apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
data.requestId = apg.apgLib.utils.charsToString(chars, phraseIndex, phraseLength); | ||
} | ||
@@ -266,6 +266,9 @@ return ret; | ||
parser.ast.callbacks['request-id'] = requestId; | ||
const resources = function(state, chars, phraseIndex, phraseLength, data) { | ||
const resources = function (state, chars, phraseIndex, phraseLength, data) { | ||
const ret = id.SEM_OK; | ||
if (state === id.SEM_PRE) { | ||
data.resources = apgLib.utils.charsToString(chars, phraseIndex, phraseLength).slice(3).split('\n- '); | ||
data.resources = apg.apgLib.utils | ||
.charsToString(chars, phraseIndex, phraseLength) | ||
.slice(3) | ||
.split('\n- '); | ||
} | ||
@@ -279,6 +282,5 @@ return ret; | ||
} | ||
const elements = { | ||
}; | ||
const elements = {}; | ||
parser.ast.translate(elements); | ||
for (const [key, value] of Object.entries(elements)){ | ||
for (const [key, value] of Object.entries(elements)) { | ||
this[key] = value; | ||
@@ -288,3 +290,2 @@ } | ||
} | ||
//# sourceMappingURL=abnf.js.map |
import * as multiformats from 'multiformats'; | ||
import { SiweMessage } from './siwe'; | ||
import { SiweMessage } from './siwe.js'; | ||
export declare type Header = { | ||
@@ -4,0 +4,0 @@ t: string; |
@@ -0,1 +1,10 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
import { verifyMessage } from '@ethersproject/wallet'; | ||
@@ -5,11 +14,10 @@ import * as dagCbor from '@ipld/dag-cbor'; | ||
import { sha256 as hasher } from 'multiformats/hashes/sha2'; | ||
import { SiweMessage } from './siwe'; | ||
import { SiweMessage } from './siwe.js'; | ||
import { AccountId } from 'caip'; | ||
var Cacao1; | ||
export { Cacao1 as Cacao }; | ||
(function(Cacao) { | ||
export var Cacao; | ||
(function (Cacao) { | ||
function fromSiweMessage(siweMessage) { | ||
const cacao = { | ||
h: { | ||
t: 'eip4361-eip191' | ||
t: 'eip4361-eip191', | ||
}, | ||
@@ -22,8 +30,8 @@ p: { | ||
version: siweMessage.version, | ||
nonce: siweMessage.nonce | ||
} | ||
nonce: siweMessage.nonce, | ||
}, | ||
}; | ||
if (siweMessage.signature) { | ||
cacao.s = { | ||
s: siweMessage.signature | ||
s: siweMessage.signature, | ||
}; | ||
@@ -49,4 +57,3 @@ } | ||
Cacao.fromSiweMessage = fromSiweMessage; | ||
function verify(cacao, options = { | ||
}) { | ||
function verify(cacao, options = {}) { | ||
if (cacao.h.t === 'eip4361-eip191') { | ||
@@ -78,19 +85,17 @@ return verifyEIP191Signature(cacao, options); | ||
Cacao.verifyEIP191Signature = verifyEIP191Signature; | ||
})(Cacao1 || (Cacao1 = { | ||
})); | ||
var CacaoBlock1; | ||
export { CacaoBlock1 as CacaoBlock }; | ||
(function(CacaoBlock) { | ||
async function fromCacao(cacao) { | ||
const block = await Block.encode({ | ||
value: cacao, | ||
codec: dagCbor, | ||
hasher: hasher | ||
})(Cacao || (Cacao = {})); | ||
export var CacaoBlock; | ||
(function (CacaoBlock) { | ||
function fromCacao(cacao) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const block = yield Block.encode({ | ||
value: cacao, | ||
codec: dagCbor, | ||
hasher: hasher, | ||
}); | ||
return block; | ||
}); | ||
return block; | ||
} | ||
CacaoBlock.fromCacao = fromCacao; | ||
})(CacaoBlock1 || (CacaoBlock1 = { | ||
})); | ||
})(CacaoBlock || (CacaoBlock = {})); | ||
//# sourceMappingURL=cacao.js.map |
@@ -1,2 +0,2 @@ | ||
export * from './siwe'; | ||
export * from './cacao'; | ||
export * from './siwe.js'; | ||
export * from './cacao.js'; |
@@ -1,4 +0,3 @@ | ||
export * from './siwe'; | ||
export * from './cacao'; | ||
export * from './siwe.js'; | ||
export * from './cacao.js'; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
import type { Cacao } from './cacao'; | ||
import type { Cacao } from './cacao.js'; | ||
export declare enum ErrorTypes { | ||
@@ -3,0 +3,0 @@ INVALID_SIGNATURE = "Invalid signature.", |
136
lib/siwe.js
@@ -1,18 +0,34 @@ | ||
import { ParsedMessage as ABNFParsedMessage } from './abnf'; | ||
import { ParsedMessage as ABNFParsedMessage } from './abnf.js'; | ||
import { AccountId, ChainId } from 'caip'; | ||
var ErrorTypes1; | ||
export { ErrorTypes1 as ErrorTypes, }; | ||
(function(ErrorTypes) { | ||
ErrorTypes[/**Thrown when the `validate()` function can verify the message. */ "INVALID_SIGNATURE"] = 'Invalid signature.'; | ||
ErrorTypes[/**Thrown when the `expirationTime` is present and in the past. */ "EXPIRED_MESSAGE"] = 'Expired message.'; | ||
ErrorTypes[/**Thrown when some required field is missing. */ "MALFORMED_SESSION"] = 'Malformed session.'; | ||
})(ErrorTypes1 || (ErrorTypes1 = { | ||
})); | ||
var SignatureType1; | ||
export { SignatureType1 as SignatureType, }; | ||
(function(SignatureType) { | ||
SignatureType[/**EIP-191 signature scheme */ "PERSONAL_SIGNATURE"] = 'Personal signature'; | ||
})(SignatureType1 || (SignatureType1 = { | ||
})); | ||
export var ErrorTypes; | ||
(function (ErrorTypes) { | ||
ErrorTypes["INVALID_SIGNATURE"] = "Invalid signature."; | ||
ErrorTypes["EXPIRED_MESSAGE"] = "Expired message."; | ||
ErrorTypes["MALFORMED_SESSION"] = "Malformed session."; | ||
})(ErrorTypes || (ErrorTypes = {})); | ||
export var SignatureType; | ||
(function (SignatureType) { | ||
SignatureType["PERSONAL_SIGNATURE"] = "Personal signature"; | ||
})(SignatureType || (SignatureType = {})); | ||
export class SiweMessage { | ||
constructor(param) { | ||
if (typeof param === 'string') { | ||
const parsedMessage = new ABNFParsedMessage(param); | ||
this.domain = parsedMessage.domain; | ||
this.address = parsedMessage.address; | ||
this.statement = parsedMessage.statement; | ||
this.uri = parsedMessage.uri; | ||
this.version = parsedMessage.version; | ||
this.nonce = parsedMessage.nonce; | ||
this.issuedAt = parsedMessage.issuedAt; | ||
this.expirationTime = parsedMessage.expirationTime; | ||
this.notBefore = parsedMessage.notBefore; | ||
this.requestId = parsedMessage.requestId; | ||
this.chainId = parsedMessage.chainId; | ||
this.resources = parsedMessage.resources; | ||
} | ||
else { | ||
Object.assign(this, param); | ||
} | ||
} | ||
static fromCacao(cacao) { | ||
@@ -32,19 +48,9 @@ const account = AccountId.parse(cacao.p.iss.replace('did:pkh:', '')); | ||
chainId: new ChainId(account.chainId).reference, | ||
resources: cacao.p.resources | ||
resources: cacao.p.resources, | ||
}); | ||
} | ||
/** | ||
* This function can be used to retrieve an EIP-4361 formated message for | ||
* signature, although you can call it directly it's advised to use | ||
* [signMessage()] instead which will resolve to the correct method based | ||
* on the [type] attribute of this object, in case of other formats being | ||
* implemented. | ||
* @returns {string} EIP-4361 formated message, ready for EIP-191 signing. | ||
*/ toMessage() { | ||
toMessage() { | ||
const header = `${this.domain} wants you to sign in with your Ethereum account:`; | ||
const uriField = `URI: ${this.uri}`; | ||
let prefix = [ | ||
header, | ||
this.address | ||
].join('\n'); | ||
let prefix = [header, this.address].join('\n'); | ||
const versionField = `Version: ${this.version}`; | ||
@@ -55,7 +61,3 @@ if (!this.nonce) { | ||
const nonceField = `Nonce: ${this.nonce}`; | ||
const suffixArray = [ | ||
uriField, | ||
versionField, | ||
nonceField | ||
]; | ||
const suffixArray = [uriField, versionField, nonceField]; | ||
if (this.issuedAt) { | ||
@@ -80,67 +82,25 @@ Date.parse(this.issuedAt); | ||
if (this.resources) { | ||
suffixArray.push([ | ||
`Resources:`, | ||
...this.resources.map((x)=>`- ${x}` | ||
) | ||
].join('\n')); | ||
suffixArray.push([`Resources:`, ...this.resources.map((x) => `- ${x}`)].join('\n')); | ||
} | ||
const suffix = suffixArray.join('\n'); | ||
if (this.statement) { | ||
prefix = [ | ||
prefix, | ||
this.statement | ||
].join('\n\n'); | ||
prefix = [prefix, this.statement].join('\n\n'); | ||
} | ||
return [ | ||
prefix, | ||
suffix | ||
].join('\n\n'); | ||
return [prefix, suffix].join('\n\n'); | ||
} | ||
/** | ||
* This method parses all the fields in the object and creates a sign | ||
* message according with the type defined. | ||
* @returns {string} Returns a message ready to be signed according with the | ||
* type defined in the object. | ||
*/ signMessage() { | ||
signMessage() { | ||
let message; | ||
switch(this.type){ | ||
case SignatureType1.PERSONAL_SIGNATURE: | ||
{ | ||
message = this.toMessage(); | ||
break; | ||
} | ||
default: | ||
{ | ||
message = this.toMessage(); | ||
break; | ||
} | ||
switch (this.type) { | ||
case SignatureType.PERSONAL_SIGNATURE: { | ||
message = this.toMessage(); | ||
break; | ||
} | ||
default: { | ||
message = this.toMessage(); | ||
break; | ||
} | ||
} | ||
return message; | ||
} | ||
/** | ||
* Creates a parsed Sign-In with Ethereum Message (EIP-4361) object from a | ||
* string or an object. If a string is used an ABNF parser is called to | ||
* validate the parameter, otherwise the fields are attributed. | ||
* @param param {string | SiweMessage} Sign message as a string or an object. | ||
*/ constructor(param){ | ||
if (typeof param === 'string') { | ||
const parsedMessage = new ABNFParsedMessage(param); | ||
this.domain = parsedMessage.domain; | ||
this.address = parsedMessage.address; | ||
this.statement = parsedMessage.statement; | ||
this.uri = parsedMessage.uri; | ||
this.version = parsedMessage.version; | ||
this.nonce = parsedMessage.nonce; | ||
this.issuedAt = parsedMessage.issuedAt; | ||
this.expirationTime = parsedMessage.expirationTime; | ||
this.notBefore = parsedMessage.notBefore; | ||
this.requestId = parsedMessage.requestId; | ||
this.chainId = parsedMessage.chainId; | ||
this.resources = parsedMessage.resources; | ||
} else { | ||
Object.assign(this, param); | ||
} | ||
} | ||
} | ||
//# sourceMappingURL=siwe.js.map |
{ | ||
"name": "ceramic-cacao", | ||
"version": "0.0.9", | ||
"version": "0.0.10", | ||
"description": "Typescript library for Ceramic OCAP", | ||
@@ -13,6 +13,7 @@ "main": "lib/index.js", | ||
], | ||
"sideEffects": false, | ||
"scripts": { | ||
"test": "npm run build && jest", | ||
"build": "swc src --out-dir lib && tsc -p tsconfig.json --emitDeclarationOnly", | ||
"lint": "eslint ./src --ext .js,.ts", | ||
"test": "./node_modules/.bin/jest", | ||
"build": "./node_modules/.bin/tsc --project tsconfig.build.json", | ||
"lint": "./node_modules/.bin/eslint ./src --ext .js,.ts", | ||
"prebuild": "npm run clean", | ||
@@ -33,16 +34,17 @@ "prepublishOnly": "npm run build", | ||
"devDependencies": { | ||
"@swc/cli": "^0.1.51", | ||
"@swc/core": "^1.2.110", | ||
"@swc/jest": "^0.2.5", | ||
"@types/jest": "^27.0.2", | ||
"@types/node": "^16.11.7", | ||
"@babel/core": "^7.16.7", | ||
"@babel/preset-env": "^7.16.8", | ||
"@babel/preset-typescript": "^7.16.7", | ||
"@types/jest": "^27.4.0", | ||
"@types/node": "^16.11.19", | ||
"@typescript-eslint/eslint-plugin": "^5.4.0", | ||
"@typescript-eslint/parser": "^5.4.0", | ||
"eslint": "^8.2.0", | ||
"babel-jest": "^27.4.6", | ||
"eslint": "^8.6.0", | ||
"eslint-config-3box": "^0.4.0", | ||
"jest": "^27.3.1", | ||
"jest": "^27.4.7", | ||
"jest-resolver-enhanced": "^1.0.1", | ||
"prettier": "^2.4.1", | ||
"regenerator-runtime": "^0.13.9", | ||
"typescript": "^4.4.4" | ||
"typescript": "^4.5.4" | ||
}, | ||
@@ -49,0 +51,0 @@ "dependencies": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
35503
15
15
528