|
69 | 69 | } |
70 | 70 | } |
71 | 71 |
|
| 72 | + // UTF-8-encode strings, base64 everything — the SWIP's |
| 73 | + // `string | Uint8Array | ArrayBuffer` payload contract for |
| 74 | + // writeFeedEntry and the chunk methods ("Strings are encoded as |
| 75 | + // UTF-8"). Distinct from publishFiles' `bytes: string` allowance, |
| 76 | + // where a string is already base64. |
| 77 | + function __payloadToBase64(data) { |
| 78 | + if (typeof data === 'string') { |
| 79 | + return __toBase64(new TextEncoder().encode(data)); |
| 80 | + } |
| 81 | + return __toBase64(data); |
| 82 | + } |
| 83 | + |
| 84 | + // Per-method param normalization shared by request() and the |
| 85 | + // convenience wrappers, so `request({method, params})` stays |
| 86 | + // byte-equivalent to the wrapper call (SWIP §"Convenience Methods"). |
| 87 | + // Typed arrays / ArrayBuffers become base64 (WKWebView's typed-array |
| 88 | + // bridging is version-dependent); `bigint` spans become decimal |
| 89 | + // strings (postMessage can't serialize BigInt). |
| 90 | + function normalizeParams(method, params) { |
| 91 | + params = params || {}; |
| 92 | + if (method === 'swarm_publishFiles' && Array.isArray(params.files)) { |
| 93 | + return Object.assign({}, params, { |
| 94 | + files: params.files.map(function (f) { |
| 95 | + return { |
| 96 | + path: f.path, |
| 97 | + contentType: f.contentType, |
| 98 | + bytes: __toBase64(f.bytes), |
| 99 | + }; |
| 100 | + }), |
| 101 | + }); |
| 102 | + } |
| 103 | + if (method === 'swarm_writeFeedEntry' |
| 104 | + && params.data !== undefined && params.data !== null) { |
| 105 | + return Object.assign({}, params, { data: __payloadToBase64(params.data) }); |
| 106 | + } |
| 107 | + if (method === 'swarm_publishChunk' || method === 'swarm_writeSingleOwnerChunk') { |
| 108 | + var next = Object.assign({}, params); |
| 109 | + if (params.data !== undefined && params.data !== null) { |
| 110 | + next.data = __payloadToBase64(params.data); |
| 111 | + } |
| 112 | + if (typeof params.span === 'bigint') { |
| 113 | + next.span = params.span.toString(); |
| 114 | + } |
| 115 | + return next; |
| 116 | + } |
| 117 | + return params; |
| 118 | + } |
| 119 | + |
| 120 | + // Chunk-read spans above Number.MAX_SAFE_INTEGER cross the bridge as |
| 121 | + // decimal strings; surface them as `bigint` per the SWIP's |
| 122 | + // `span: number | bigint` result contract. |
| 123 | + function postProcessResult(method, result) { |
| 124 | + if ((method === 'swarm_readChunk' || method === 'swarm_readSingleOwnerChunk') |
| 125 | + && result && typeof result.span === 'string') { |
| 126 | + result.span = BigInt(result.span); |
| 127 | + } |
| 128 | + return result; |
| 129 | + } |
| 130 | + |
72 | 131 | function makeRequest(method, params) { |
73 | 132 | const id = ++requestId; |
| 133 | + var normalized = normalizeParams(method, params); |
74 | 134 | return new Promise(function (resolve, reject) { |
75 | | - pendingRequests.set(id, { resolve: resolve, reject: reject }); |
76 | | - postToNative({ type: 'request', id: id, method: method, params: params || {} }); |
| 135 | + pendingRequests.set(id, { resolve: resolve, reject: reject, method: method }); |
| 136 | + postToNative({ type: 'request', id: id, method: method, params: normalized }); |
77 | 137 | // 5 min ceiling — covers chain-tx-blocked publish/feed-write paths. |
78 | 138 | // Reads + capability checks resolve in tens of ms, so the cap only |
79 | 139 | // bites on misbehaving native handlers. |
|
123 | 183 | getUploadStatus: function (params) { return makeRequest('swarm_getUploadStatus', params); }, |
124 | 184 | createFeed: function (params) { return makeRequest('swarm_createFeed', params); }, |
125 | 185 | updateFeed: function (params) { return makeRequest('swarm_updateFeed', params); }, |
126 | | - writeFeedEntry: function (params) { |
127 | | - // Normalize `data` to base64 so the native side has one shape |
128 | | - // to decode regardless of whether the dapp passed a string, |
129 | | - // Uint8Array, or ArrayBuffer. Strings are UTF-8-encoded first |
130 | | - // so SOC payload bytes match what the dapp wrote (the SOC |
131 | | - // stores opaque bytes; bee doesn't care about encoding). |
132 | | - var normalized = params; |
133 | | - if (params && params.data !== undefined && params.data !== null) { |
134 | | - var encoded; |
135 | | - if (typeof params.data === 'string') { |
136 | | - encoded = __toBase64(new TextEncoder().encode(params.data)); |
137 | | - } else { |
138 | | - encoded = __toBase64(params.data); |
139 | | - } |
140 | | - normalized = Object.assign({}, params, { data: encoded }); |
141 | | - } |
142 | | - return makeRequest('swarm_writeFeedEntry', normalized); |
143 | | - }, |
| 186 | + // Payload/span normalization happens in normalizeParams so the |
| 187 | + // request() path behaves identically. |
| 188 | + writeFeedEntry: function (params) { return makeRequest('swarm_writeFeedEntry', params); }, |
144 | 189 | readFeedEntry: function (params) { return makeRequest('swarm_readFeedEntry', params); }, |
145 | 190 | listFeeds: function () { return makeRequest('swarm_listFeeds'); }, |
| 191 | + publishChunk: function (params) { return makeRequest('swarm_publishChunk', params); }, |
| 192 | + readChunk: function (params) { return makeRequest('swarm_readChunk', params); }, |
| 193 | + writeSingleOwnerChunk: function (params) { return makeRequest('swarm_writeSingleOwnerChunk', params); }, |
| 194 | + readSingleOwnerChunk: function (params) { return makeRequest('swarm_readSingleOwnerChunk', params); }, |
| 195 | + getSigningIdentity: function () { return makeRequest('swarm_getSigningIdentity'); }, |
146 | 196 |
|
147 | 197 | on: function (event, handler) { |
148 | 198 | if (eventListeners[event]) eventListeners[event].push(handler); |
|
175 | 225 | if (error.data) err.data = error.data; |
176 | 226 | pending.reject(err); |
177 | 227 | } else { |
178 | | - pending.resolve(result); |
| 228 | + pending.resolve(postProcessResult(pending.method, result)); |
179 | 229 | } |
180 | 230 | }, |
181 | 231 | __handleEvent: function (event, data) { |
|
0 commit comments