Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 42 additions & 36 deletions connect/src/client/hb.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import base64url from 'base64url'
import { joinUrl } from '../lib/utils.js'
import { encode } from './hb-encode.js'
import { toHttpSigner, toDataItemSigner } from './signer.js'
import { verboseLog } from '../logger.js'

let reqFormatCache = {}

/**
* Map data item members to corresponding HB HTTP message
* shape
*/
export async function encodeDataItem ({ processId, data, tags, anchor }) {
export async function encodeDataItem({ processId, data, tags, anchor }) {
const obj = {}

if (processId) obj.target = processId
Expand All @@ -30,7 +31,7 @@ export async function encodeDataItem ({ processId, data, tags, anchor }) {
return res
}

function toSigBaseArgs ({ url, method, headers, includePath = false }) {
function toSigBaseArgs({ url, method, headers, includePath = false }) {
headers = new Headers(headers)
return {
/**
Expand All @@ -48,7 +49,7 @@ function toSigBaseArgs ({ url, method, headers, includePath = false }) {
}
}

export function httpSigName (address) {
export function httpSigName(address) {
const decoded = base64url.toBuffer(address)
const hexString = [...decoded.subarray(1, 9)]
.map(byte => byte.toString(16).padStart(2, '0'))
Expand Down Expand Up @@ -96,7 +97,7 @@ export function processIdWith({ logger: _logger, signer, HB_URL }) {
))
.map(logger.tap('Sending HTTP signed message to HB: %o'))
.chain(fromPromise(res => {

return hashAndBase64(extractSignature(res.headers.Signature))
}))
.toPromise()
Expand All @@ -108,23 +109,26 @@ export function requestWith(args) {
let signingFormat = args.signingFormat
const logger = _logger.child('request')

return async function(fields) {
return async function (fields) {
const { path, method, ...restFields } = fields

signingFormat = fields.signingFormat
if (!signingFormat) {
signingFormat = reqFormatCache[fields.path] ?? 'HTTP'
}

try {
let fetch_req = {}

verboseLog('SIGNING FORMAT: ', signingFormat, '. REQUEST: ', fields);

let fetch_req = { }
//logger.tap('SIGNING FORMAT: ', signingFormat, '. REQUEST: ', fields)()
if (signingFormat === 'ANS-104') {
const ans104Request = toANS104Request(restFields)
// logger.tap('ANS-104 REQUEST PRE-SIGNING: ', ans104Request)()
verboseLog('ANS-104 REQUEST PRE-SIGNING: ', ans104Request)

const signedRequest = await toDataItemSigner(signer)(ans104Request.item)
//logger.tap('SIGNED ANS-104 ITEM: ', signedRequest)()
verboseLog('SIGNED ANS-104 ITEM: ', signedRequest)

fetch_req = {
body: signedRequest.raw,
url: joinUrl({ url: HB_URL, path }),
Expand All @@ -141,63 +145,65 @@ export function requestWith(args) {
method: method,
headers: req.headers
})

const signedRequest = await toHttpSigner(signer)(signingArgs)
fetch_req = { ...signedRequest, body: req.body, path, method }
}

// Log the request
// logger.tap('Sending signed message to HB: %o')(fetch_req)


verboseLog('Sending signed message to HB: %o')

// Step 4: Send the request
const res = await fetch(fetch_req.url, {
method: fetch_req.method,
headers: fetch_req.headers,
body: fetch_req.body,
redirect: 'follow'
const res = await fetch(fetch_req.url, {
method: fetch_req.method,
headers: fetch_req.headers,
body: fetch_req.body,
redirect: 'follow'
})
// console.log('PUSH FORMAT: ', signingFormat, '. RESPONSE:', res)

verboseLog('PUSH FORMAT: ', signingFormat, '. RESPONSE:', res)

// Step 5: Handle specific status codes
if (res.status === 422 && signingFormat === 'HTTP') {
// Try again with different signing format
reqFormatCache[fields.path] = 'ANS-104'
return requestWith({ ...args, signingFormat: 'ANS-104' })(fields)
}


if (res.status == 500) {
verboseLog('ERROR RESPONSE: ', res)
throw new Error(`${res.status}: ${await res.text()}`)
}

if (res.status === 404) {
// logger.tap('ERROR RESPONSE: ', res)()
//process.exit(1)
verboseLog('ERROR RESPONSE: ', res)
throw new Error(`${res.status}: ${await res.text()}`)
}

if (res.status >= 400) {
// logger.tap('ERROR RESPONSE: ', res)()
process.exit(1)
logger.tap('ERROR RESPONSE: ', res)
throw new Error(`${res.status}: ${await res.text()}`)
}

if (res.status >= 300) {
return res
}

let body = await res.text()
// console.log(body)
// Step 6: Return the response
return {
headers: res.headers,
body: body
body: body
}
} catch (error) {
// Handle errors appropriately
//console.error("Request failed:", error)
verboseLog('ERROR RESPONSE: ', error)
throw error
}
}
}

export function toANS104Request(fields) {
// logger.tap('TO ANS 104 REQUEST: ', fields)()
verboseLog('TO ANS 104 REQUEST: ', fields)
const dataItem = {
target: fields.target,
anchor: fields.anchor ?? '',
Expand Down Expand Up @@ -234,7 +240,7 @@ export function toANS104Request(fields) {
]),
data: fields?.data || ''
}
// logger.tap('ANS104 REQUEST: ', dataItem)()
verboseLog('ANS104 REQUEST: ', dataItem)
return { headers: { 'Content-Type': 'application/ans104', 'codec-device': 'ans104@1.0' }, item: dataItem }
}

6 changes: 6 additions & 0 deletions connect/src/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ export const createLogger = (name = '@permaweb/aoconnect') => {

return logger
}

export const verboseLog = (...args) => {
if (process.env.DEBUG) {
console.log(...args)
}
}
2 changes: 1 addition & 1 deletion dev-cli/src/starters/lua/ao.lua
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ function ao.spawn(module, msg)
Action = "Spawned",
From = ao.id,
["Reference"] = spawnRef
}, callback)
}, callback)`
end

spawn.receive = function()
Expand Down