@arcadiasystems/morse-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/LICENSE +21 -0
- package/README.md +404 -0
- package/dist/clients.d.ts +12 -0
- package/dist/clients.d.ts.map +1 -0
- package/dist/clients.js +6 -0
- package/dist/clients.js.map +1 -0
- package/dist/codecs.d.ts +45 -0
- package/dist/codecs.d.ts.map +1 -0
- package/dist/codecs.js +132 -0
- package/dist/codecs.js.map +1 -0
- package/dist/compatibility.d.ts +22 -0
- package/dist/compatibility.d.ts.map +1 -0
- package/dist/compatibility.js +22 -0
- package/dist/compatibility.js.map +1 -0
- package/dist/config.d.ts +92 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +85 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +101 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +214 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/ops/cap.d.ts +79 -0
- package/dist/ops/cap.d.ts.map +1 -0
- package/dist/ops/cap.js +104 -0
- package/dist/ops/cap.js.map +1 -0
- package/dist/ops/collection.d.ts +50 -0
- package/dist/ops/collection.d.ts.map +1 -0
- package/dist/ops/collection.js +55 -0
- package/dist/ops/collection.js.map +1 -0
- package/dist/ops/entry-from-bytes.d.ts +129 -0
- package/dist/ops/entry-from-bytes.d.ts.map +1 -0
- package/dist/ops/entry-from-bytes.js +137 -0
- package/dist/ops/entry-from-bytes.js.map +1 -0
- package/dist/ops/entry.d.ts +173 -0
- package/dist/ops/entry.d.ts.map +1 -0
- package/dist/ops/entry.js +235 -0
- package/dist/ops/entry.js.map +1 -0
- package/dist/ops/index.d.ts +9 -0
- package/dist/ops/index.d.ts.map +1 -0
- package/dist/ops/index.js +9 -0
- package/dist/ops/index.js.map +1 -0
- package/dist/ops/internal.d.ts +21 -0
- package/dist/ops/internal.d.ts.map +1 -0
- package/dist/ops/internal.js +42 -0
- package/dist/ops/internal.js.map +1 -0
- package/dist/ops/publication.d.ts +74 -0
- package/dist/ops/publication.d.ts.map +1 -0
- package/dist/ops/publication.js +123 -0
- package/dist/ops/publication.js.map +1 -0
- package/dist/ptb/cap.d.ts +36 -0
- package/dist/ptb/cap.d.ts.map +1 -0
- package/dist/ptb/cap.js +44 -0
- package/dist/ptb/cap.js.map +1 -0
- package/dist/ptb/collection.d.ts +27 -0
- package/dist/ptb/collection.d.ts.map +1 -0
- package/dist/ptb/collection.js +33 -0
- package/dist/ptb/collection.js.map +1 -0
- package/dist/ptb/entry.d.ts +104 -0
- package/dist/ptb/entry.d.ts.map +1 -0
- package/dist/ptb/entry.js +155 -0
- package/dist/ptb/entry.js.map +1 -0
- package/dist/ptb/index.d.ts +9 -0
- package/dist/ptb/index.d.ts.map +1 -0
- package/dist/ptb/index.js +9 -0
- package/dist/ptb/index.js.map +1 -0
- package/dist/ptb/internal.d.ts +11 -0
- package/dist/ptb/internal.d.ts.map +1 -0
- package/dist/ptb/internal.js +12 -0
- package/dist/ptb/internal.js.map +1 -0
- package/dist/ptb/publication.d.ts +51 -0
- package/dist/ptb/publication.d.ts.map +1 -0
- package/dist/ptb/publication.js +61 -0
- package/dist/ptb/publication.js.map +1 -0
- package/dist/read/entry-bcs.d.ts +47 -0
- package/dist/read/entry-bcs.d.ts.map +1 -0
- package/dist/read/entry-bcs.js +36 -0
- package/dist/read/entry-bcs.js.map +1 -0
- package/dist/read/index.d.ts +5 -0
- package/dist/read/index.d.ts.map +1 -0
- package/dist/read/index.js +5 -0
- package/dist/read/index.js.map +1 -0
- package/dist/read/reader.d.ts +148 -0
- package/dist/read/reader.d.ts.map +1 -0
- package/dist/read/reader.js +403 -0
- package/dist/read/reader.js.map +1 -0
- package/dist/seal/adapter.d.ts +56 -0
- package/dist/seal/adapter.d.ts.map +1 -0
- package/dist/seal/adapter.js +7 -0
- package/dist/seal/adapter.js.map +1 -0
- package/dist/seal/default-adapter.d.ts +90 -0
- package/dist/seal/default-adapter.d.ts.map +1 -0
- package/dist/seal/default-adapter.js +187 -0
- package/dist/seal/default-adapter.js.map +1 -0
- package/dist/seal/identity.d.ts +31 -0
- package/dist/seal/identity.d.ts.map +1 -0
- package/dist/seal/identity.js +79 -0
- package/dist/seal/identity.js.map +1 -0
- package/dist/seal/index.d.ts +8 -0
- package/dist/seal/index.d.ts.map +1 -0
- package/dist/seal/index.js +7 -0
- package/dist/seal/index.js.map +1 -0
- package/dist/types.d.ts +160 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +33 -0
- package/dist/types.js.map +1 -0
- package/dist/wallets/adapter.d.ts +34 -0
- package/dist/wallets/adapter.d.ts.map +1 -0
- package/dist/wallets/adapter.js +6 -0
- package/dist/wallets/adapter.js.map +1 -0
- package/dist/wallets/index.d.ts +7 -0
- package/dist/wallets/index.d.ts.map +1 -0
- package/dist/wallets/index.js +6 -0
- package/dist/wallets/index.js.map +1 -0
- package/dist/wallets/keypair-adapter.d.ts +31 -0
- package/dist/wallets/keypair-adapter.d.ts.map +1 -0
- package/dist/wallets/keypair-adapter.js +210 -0
- package/dist/wallets/keypair-adapter.js.map +1 -0
- package/dist/wallets/wallet-standard-signer.d.ts +118 -0
- package/dist/wallets/wallet-standard-signer.d.ts.map +1 -0
- package/dist/wallets/wallet-standard-signer.js +207 -0
- package/dist/wallets/wallet-standard-signer.js.map +1 -0
- package/dist/walrus/adapter.d.ts +91 -0
- package/dist/walrus/adapter.d.ts.map +1 -0
- package/dist/walrus/adapter.js +11 -0
- package/dist/walrus/adapter.js.map +1 -0
- package/dist/walrus/default-adapter.d.ts +104 -0
- package/dist/walrus/default-adapter.d.ts.map +1 -0
- package/dist/walrus/default-adapter.js +146 -0
- package/dist/walrus/default-adapter.js.map +1 -0
- package/dist/walrus/default-read-adapter.d.ts +89 -0
- package/dist/walrus/default-read-adapter.d.ts.map +1 -0
- package/dist/walrus/default-read-adapter.js +81 -0
- package/dist/walrus/default-read-adapter.js.map +1 -0
- package/dist/walrus/http-aggregator-read-adapter.d.ts +107 -0
- package/dist/walrus/http-aggregator-read-adapter.d.ts.map +1 -0
- package/dist/walrus/http-aggregator-read-adapter.js +174 -0
- package/dist/walrus/http-aggregator-read-adapter.js.map +1 -0
- package/dist/walrus/http-publisher-write-adapter.d.ts +97 -0
- package/dist/walrus/http-publisher-write-adapter.d.ts.map +1 -0
- package/dist/walrus/http-publisher-write-adapter.js +249 -0
- package/dist/walrus/http-publisher-write-adapter.js.map +1 -0
- package/dist/walrus/index.d.ts +11 -0
- package/dist/walrus/index.d.ts.map +1 -0
- package/dist/walrus/index.js +11 -0
- package/dist/walrus/index.js.map +1 -0
- package/dist/walrus/quilt-patch-id.d.ts +34 -0
- package/dist/walrus/quilt-patch-id.d.ts.map +1 -0
- package/dist/walrus/quilt-patch-id.js +103 -0
- package/dist/walrus/quilt-patch-id.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Signer` subclass that delegates signing to a wallet-standard wallet
|
|
3
|
+
* (Suiet, Sui Wallet, Slush, etc.) via the dapp-kit hooks `useSignTransaction`
|
|
4
|
+
* and `useSignPersonalMessage`. The user's private key never leaves the
|
|
5
|
+
* wallet.
|
|
6
|
+
*
|
|
7
|
+
* Use this when passing a signer to libraries that accept the Sui
|
|
8
|
+
* `@mysten/sui/cryptography` `Signer` abstract — `@mysten/walrus`'s
|
|
9
|
+
* `WalrusClient.writeBlob({ signer })` and `@mysten/seal`'s
|
|
10
|
+
* `SessionKey.create({ signer })`.
|
|
11
|
+
*
|
|
12
|
+
* Methods called by Walrus on the signer: `toSuiAddress`,
|
|
13
|
+
* `signAndExecuteTransaction({ transaction, client })`. Methods called by
|
|
14
|
+
* Seal: `getPublicKey().toSuiAddress()`, `signPersonalMessage(bytes)`. The
|
|
15
|
+
* `sign(bytes)` raw-byte primitive is intentionally not implemented;
|
|
16
|
+
* wallets do not expose raw signing for security reasons. If a future
|
|
17
|
+
* library version invokes `sign(bytes)` or `signTransaction(bytes)`
|
|
18
|
+
* directly (raw-byte form, not the override), this signer throws.
|
|
19
|
+
*/
|
|
20
|
+
import { Signer, } from "@mysten/sui/cryptography";
|
|
21
|
+
import { Ed25519PublicKey } from "@mysten/sui/keypairs/ed25519";
|
|
22
|
+
import { PasskeyPublicKey } from "@mysten/sui/keypairs/passkey";
|
|
23
|
+
import { Secp256k1PublicKey } from "@mysten/sui/keypairs/secp256k1";
|
|
24
|
+
import { Secp256r1PublicKey } from "@mysten/sui/keypairs/secp256r1";
|
|
25
|
+
import { normalizeSuiAddress } from "@mysten/sui/utils";
|
|
26
|
+
import { ZkLoginPublicIdentifier } from "@mysten/sui/zklogin";
|
|
27
|
+
import { ConfigurationError } from "../errors.js";
|
|
28
|
+
/**
|
|
29
|
+
* `Signer` backed by wallet-standard callbacks. Supplies methods Walrus and
|
|
30
|
+
* Seal call; throws on raw-byte signing, which wallets do not expose.
|
|
31
|
+
*/
|
|
32
|
+
export class WalletStandardSigner extends Signer {
|
|
33
|
+
#publicKey;
|
|
34
|
+
#keyScheme;
|
|
35
|
+
#signTransaction;
|
|
36
|
+
#signPersonalMessage;
|
|
37
|
+
constructor(options) {
|
|
38
|
+
super();
|
|
39
|
+
this.#publicKey = options.publicKey;
|
|
40
|
+
this.#keyScheme = options.keyScheme;
|
|
41
|
+
this.#signTransaction = options.signTransaction;
|
|
42
|
+
this.#signPersonalMessage = options.signPersonalMessage;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build a signer from a wallet-standard `WalletAccount` plus the wallet's
|
|
46
|
+
* `signTransaction` / `signPersonalMessage` callbacks. Tries every plausible
|
|
47
|
+
* interpretation of `account.publicKey` and returns the one whose derived
|
|
48
|
+
* address matches `account.address`.
|
|
49
|
+
*
|
|
50
|
+
* Wallet-standard does not mandate a single encoding for `publicKey`:
|
|
51
|
+
* Suiet emits raw bytes (e.g. 32 for Ed25519), Slush emits Sui's canonical
|
|
52
|
+
* with-flag form (e.g. `0x00 || 32-byte raw` for Ed25519). Both are
|
|
53
|
+
* accepted; address-match disambiguates.
|
|
54
|
+
*
|
|
55
|
+
* Supported schemes: ED25519, Secp256k1, Secp256r1, Passkey (raw or
|
|
56
|
+
* flag-prefixed), and ZkLogin (variable-length identifier of the form
|
|
57
|
+
* `[1 byte iss-len][iss bytes][32 byte addressSeed]`). MultiSig is
|
|
58
|
+
* refused.
|
|
59
|
+
*
|
|
60
|
+
* Caveat for ZkLogin: the dispatch is structurally correct but
|
|
61
|
+
* end-to-end behavior against `@mysten/walrus`'s `register_blob` /
|
|
62
|
+
* `certify_blob` and `@mysten/seal`'s `SessionKey` verification has
|
|
63
|
+
* not been smoke-tested. If your users see Seal `decrypt-failed` or
|
|
64
|
+
* Walrus signature errors on zkLogin accounts, fall back to a
|
|
65
|
+
* keypair account.
|
|
66
|
+
*
|
|
67
|
+
* @throws {ConfigurationError} If the account uses multisig, or if no
|
|
68
|
+
* candidate scheme produces an address matching `account.address`.
|
|
69
|
+
*/
|
|
70
|
+
static fromAccount(account, callbacks) {
|
|
71
|
+
const { publicKey, keyScheme } = decodeAccountPublicKey(account);
|
|
72
|
+
return new WalletStandardSigner({
|
|
73
|
+
publicKey,
|
|
74
|
+
keyScheme,
|
|
75
|
+
signTransaction: callbacks.signTransaction,
|
|
76
|
+
signPersonalMessage: callbacks.signPersonalMessage,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
getKeyScheme() {
|
|
80
|
+
return this.#keyScheme;
|
|
81
|
+
}
|
|
82
|
+
getPublicKey() {
|
|
83
|
+
return this.#publicKey;
|
|
84
|
+
}
|
|
85
|
+
sign(_bytes) {
|
|
86
|
+
throw new ConfigurationError("WalletStandardSigner does not support raw-byte signing. Wallet-standard wallets only sign transactions and personal messages.");
|
|
87
|
+
}
|
|
88
|
+
async signPersonalMessage(message) {
|
|
89
|
+
return this.#signPersonalMessage({ message });
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Sign and submit a transaction. The wallet pops up to confirm; on approval
|
|
93
|
+
* it returns canonical BCS bytes plus signature. Those bytes (not any
|
|
94
|
+
* locally-built bytes) are submitted via the supplied client so the
|
|
95
|
+
* signature validates against what the wallet actually signed.
|
|
96
|
+
*/
|
|
97
|
+
async signAndExecuteTransaction({ transaction, client, }) {
|
|
98
|
+
transaction.setSenderIfNotSet(this.toSuiAddress());
|
|
99
|
+
const { bytes, signature } = await this.#signTransaction({ transaction });
|
|
100
|
+
return client.core.executeTransaction({
|
|
101
|
+
transaction: fromBase64(bytes),
|
|
102
|
+
signatures: [signature],
|
|
103
|
+
include: { transaction: true, effects: true },
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function fromBase64(value) {
|
|
108
|
+
const binary = atob(value);
|
|
109
|
+
const out = new Uint8Array(binary.length);
|
|
110
|
+
for (let i = 0; i < binary.length; i += 1) {
|
|
111
|
+
out[i] = binary.charCodeAt(i);
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Pick the `PublicKey` subclass whose Sui address matches `account.address`.
|
|
117
|
+
* Wallet-standard does not mandate a single encoding for `account.publicKey`:
|
|
118
|
+
* Suiet emits the raw key bytes; Slush emits Sui's canonical "with-flag" form
|
|
119
|
+
* (`flagByte || rawKey`). Both are valid, so the decoder tries every plausible
|
|
120
|
+
* (length, leading-byte) interpretation and picks the one whose address
|
|
121
|
+
* derivation matches the wallet-reported address. Address-match is the only
|
|
122
|
+
* reliable disambiguator because the scheme flag folds into the address hash.
|
|
123
|
+
*/
|
|
124
|
+
function decodeAccountPublicKey(account) {
|
|
125
|
+
const bytes = new Uint8Array(Array.from(account.publicKey));
|
|
126
|
+
const expected = normalizeSuiAddress(account.address);
|
|
127
|
+
const candidates = candidateInterpretations(bytes);
|
|
128
|
+
for (const { scheme, build } of candidates) {
|
|
129
|
+
let publicKey;
|
|
130
|
+
try {
|
|
131
|
+
publicKey = build();
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (normalizeSuiAddress(publicKey.toSuiAddress()) === expected) {
|
|
137
|
+
return { publicKey, keyScheme: scheme };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// ZkLogin pub identifier is `[1 byte iss-len][iss bytes][32 byte addressSeed]`,
|
|
141
|
+
// always > 33 bytes. `fromBytes({ address })` auto-tries non-legacy then
|
|
142
|
+
// legacy address derivation and throws on mismatch; treat throw as
|
|
143
|
+
// "not zkLogin" and fall through to refusal so multisig and garbage
|
|
144
|
+
// bytes don't get silently labeled as zkLogin.
|
|
145
|
+
if (bytes.length > 33) {
|
|
146
|
+
try {
|
|
147
|
+
const publicKey = ZkLoginPublicIdentifier.fromBytes(bytes, {
|
|
148
|
+
address: account.address,
|
|
149
|
+
});
|
|
150
|
+
return { publicKey, keyScheme: "ZkLogin" };
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// Fall through.
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
throw new ConfigurationError(`WalletStandardSigner: account.publicKey is ${bytes.length} bytes and matches neither a raw nor a flag-prefixed (Sui canonical) form of Ed25519, Secp256k1, Secp256r1, or Passkey, nor a zkLogin identifier, for address ${account.address}. This suggests a multisig or unknown signature scheme; implement a custom Signer.`);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Build the list of (scheme, public-key-constructor) pairs to try against
|
|
160
|
+
* `account.address`. Covers raw bytes (Suiet-style) and flag-prefixed bytes
|
|
161
|
+
* (Sui canonical / Slush-style). Order is stable but irrelevant for
|
|
162
|
+
* correctness — address-match disambiguates.
|
|
163
|
+
*/
|
|
164
|
+
function candidateInterpretations(bytes) {
|
|
165
|
+
const list = [];
|
|
166
|
+
if (bytes.length === 32) {
|
|
167
|
+
list.push({
|
|
168
|
+
scheme: "ED25519",
|
|
169
|
+
build: () => new Ed25519PublicKey(bytes),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
if (bytes.length === 33) {
|
|
173
|
+
list.push({ scheme: "Secp256k1", build: () => new Secp256k1PublicKey(bytes) }, { scheme: "Secp256r1", build: () => new Secp256r1PublicKey(bytes) }, { scheme: "Passkey", build: () => new PasskeyPublicKey(bytes) });
|
|
174
|
+
// Sui canonical Ed25519 with-flag: 0x00 || 32-byte raw key.
|
|
175
|
+
if (bytes[0] === 0x00) {
|
|
176
|
+
const inner = bytes.slice(1);
|
|
177
|
+
list.push({
|
|
178
|
+
scheme: "ED25519",
|
|
179
|
+
build: () => new Ed25519PublicKey(inner),
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (bytes.length === 34) {
|
|
184
|
+
const inner = bytes.slice(1);
|
|
185
|
+
// Sui canonical with-flag forms: flag || 33-byte compressed point.
|
|
186
|
+
if (bytes[0] === 0x01) {
|
|
187
|
+
list.push({
|
|
188
|
+
scheme: "Secp256k1",
|
|
189
|
+
build: () => new Secp256k1PublicKey(inner),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (bytes[0] === 0x02) {
|
|
193
|
+
list.push({
|
|
194
|
+
scheme: "Secp256r1",
|
|
195
|
+
build: () => new Secp256r1PublicKey(inner),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
if (bytes[0] === 0x06) {
|
|
199
|
+
list.push({
|
|
200
|
+
scheme: "Passkey",
|
|
201
|
+
build: () => new PasskeyPublicKey(inner),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return list;
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=wallet-standard-signer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-standard-signer.js","sourceRoot":"","sources":["../../src/wallets/wallet-standard-signer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write-only Walrus adapter interface. Reads are deferred to entry-fetch in
|
|
3
|
+
* a later phase; this surface intentionally exposes only what entry-write
|
|
4
|
+
* paths need.
|
|
5
|
+
*/
|
|
6
|
+
import type { Transaction } from "@mysten/sui/transactions";
|
|
7
|
+
import type { BlobObjectId, QuiltPatchId, WalrusBlobId } from "../types.js";
|
|
8
|
+
/** Storage parameters shared by blob and quilt uploads. */
|
|
9
|
+
export interface WalrusUploadCommonOptions {
|
|
10
|
+
/** Number of Walrus epochs the blob should be stored for. */
|
|
11
|
+
readonly epochs: number;
|
|
12
|
+
/** Whether the resulting blob object is deletable. The Move layer rejects non-deletable blobs. */
|
|
13
|
+
readonly deletable: boolean;
|
|
14
|
+
/** Address that will own the resulting Sui blob object; defaults to the signer. */
|
|
15
|
+
readonly owner?: string;
|
|
16
|
+
/** Cancellation signal forwarded to the underlying network layer. */
|
|
17
|
+
readonly signal?: AbortSignal;
|
|
18
|
+
}
|
|
19
|
+
/** Options for `uploadBlob`. */
|
|
20
|
+
export type UploadBlobOptions = WalrusUploadCommonOptions;
|
|
21
|
+
/** One blob to include in a quilt upload. */
|
|
22
|
+
export interface QuiltPatchInput {
|
|
23
|
+
/** Bytes for this patch. */
|
|
24
|
+
readonly contents: Uint8Array;
|
|
25
|
+
/** Identifier unique within the quilt; surfaced back in `UploadQuiltResult.patches[].identifier`. */
|
|
26
|
+
readonly identifier: string;
|
|
27
|
+
/** Optional key-value tags attached to the patch. */
|
|
28
|
+
readonly tags?: Readonly<Record<string, string>>;
|
|
29
|
+
}
|
|
30
|
+
/** Options for `uploadQuilt`. */
|
|
31
|
+
export type UploadQuiltOptions = WalrusUploadCommonOptions;
|
|
32
|
+
/** Result of `uploadBlob`. */
|
|
33
|
+
export interface UploadBlobResult {
|
|
34
|
+
readonly blobId: WalrusBlobId;
|
|
35
|
+
readonly blobObjectId: BlobObjectId;
|
|
36
|
+
}
|
|
37
|
+
/** One patch in `UploadQuiltResult`. */
|
|
38
|
+
export interface UploadQuiltPatch {
|
|
39
|
+
readonly identifier: string;
|
|
40
|
+
readonly patchId: QuiltPatchId;
|
|
41
|
+
readonly startIndex: number;
|
|
42
|
+
readonly endIndex: number;
|
|
43
|
+
}
|
|
44
|
+
/** Result of `uploadQuilt`. */
|
|
45
|
+
export interface UploadQuiltResult {
|
|
46
|
+
readonly blobId: WalrusBlobId;
|
|
47
|
+
readonly blobObjectId: BlobObjectId;
|
|
48
|
+
readonly patches: readonly UploadQuiltPatch[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Write-only Walrus client. Implementations: `DefaultWalrusWriteAdapter`
|
|
52
|
+
* (wraps `@mysten/walrus`); user-supplied adapters can substitute for tests
|
|
53
|
+
* or alternative storage backends. Errors at the boundary normalize to
|
|
54
|
+
* `TransportError` (network, IO) or `ValidationError` (malformed input).
|
|
55
|
+
*/
|
|
56
|
+
export interface WalrusWriteAdapter {
|
|
57
|
+
uploadBlob(data: Uint8Array, options: UploadBlobOptions): Promise<UploadBlobResult>;
|
|
58
|
+
uploadQuilt(patches: readonly QuiltPatchInput[], options: UploadQuiltOptions): Promise<UploadQuiltResult>;
|
|
59
|
+
}
|
|
60
|
+
/** Result of `WalrusFlowCapable.startBlobUpload`. */
|
|
61
|
+
export interface StartBlobUploadResult {
|
|
62
|
+
readonly blobObjectId: BlobObjectId;
|
|
63
|
+
readonly blobId: WalrusBlobId;
|
|
64
|
+
/**
|
|
65
|
+
* `Transaction` already containing the `walrus::blob::certify_blob` move
|
|
66
|
+
* call. Append your downstream calls (e.g. `add_entry_to_collection`) and
|
|
67
|
+
* submit the same `Transaction`.
|
|
68
|
+
*/
|
|
69
|
+
readonly certifyTransaction: Transaction;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Optional capability layered on top of `WalrusWriteAdapter`. Adapters that
|
|
73
|
+
* support driving Walrus's `writeBlobFlow` step-by-step can implement this
|
|
74
|
+
* to enable single-PTB ops like `addEntryFromBytes` / `addEncryptedEntryFromBytes`,
|
|
75
|
+
* which combine `certify_blob` with downstream contract calls in one wallet
|
|
76
|
+
* popup. Adapters without this capability fall back to the standard 2- or
|
|
77
|
+
* 3-popup paths via `uploadBlob` + downstream ops.
|
|
78
|
+
*/
|
|
79
|
+
export interface WalrusFlowCapable {
|
|
80
|
+
/**
|
|
81
|
+
* Register and upload a blob without certifying it on-chain. Returns
|
|
82
|
+
* the blob's Sui object id, content id, and the certify `Transaction`.
|
|
83
|
+
* The caller appends further move calls to `certifyTransaction` and
|
|
84
|
+
* submits once, combining certify + downstream ops into a single
|
|
85
|
+
* wallet popup.
|
|
86
|
+
*/
|
|
87
|
+
startBlobUpload(data: Uint8Array, options: UploadBlobOptions): Promise<StartBlobUploadResult>;
|
|
88
|
+
}
|
|
89
|
+
/** Type guard for the optional flow capability. */
|
|
90
|
+
export declare function isWalrusFlowCapable(walrus: WalrusWriteAdapter): walrus is WalrusWriteAdapter & WalrusFlowCapable;
|
|
91
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/walrus/adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5E,2DAA2D;AAC3D,MAAM,WAAW,yBAAyB;IACzC,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kGAAkG;IAClG,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAED,gCAAgC;AAChC,MAAM,MAAM,iBAAiB,GAAG,yBAAyB,CAAC;AAE1D,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC/B,4BAA4B;IAC5B,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;IAC9B,qGAAqG;IACrG,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACjD;AAED,iCAAiC;AACjC,MAAM,MAAM,kBAAkB,GAAG,yBAAyB,CAAC;AAE3D,8BAA8B;AAC9B,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACpC;AAED,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,+BAA+B;AAC/B,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC9C;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IAClC,UAAU,CACT,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,iBAAiB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC7B,WAAW,CACV,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,OAAO,EAAE,kBAAkB,GACzB,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC9B;AAED,qDAAqD;AACrD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,EAAE,WAAW,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IACjC;;;;;;OAMG;IACH,eAAe,CACd,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,iBAAiB,GACxB,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAClC;AAED,mDAAmD;AACnD,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,kBAAkB,GACxB,MAAM,IAAI,kBAAkB,GAAG,iBAAiB,CAKlD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write-only Walrus adapter interface. Reads are deferred to entry-fetch in
|
|
3
|
+
* a later phase; this surface intentionally exposes only what entry-write
|
|
4
|
+
* paths need.
|
|
5
|
+
*/
|
|
6
|
+
/** Type guard for the optional flow capability. */
|
|
7
|
+
export function isWalrusFlowCapable(walrus) {
|
|
8
|
+
return (typeof walrus
|
|
9
|
+
.startBlobUpload === "function");
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/walrus/adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0GH,mDAAmD;AACnD,MAAM,UAAU,mBAAmB,CAClC,MAA0B;IAE1B,OAAO,CACN,OAAQ,MAA0D;SAChE,eAAe,KAAK,UAAU,CAChC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `WalrusWriteAdapter` implementation backed by `@mysten/walrus`. Bind a
|
|
3
|
+
* `WalrusClient` to a Sui `Signer` once, then call `uploadBlob` /
|
|
4
|
+
* `uploadQuilt` per write. Read paths live elsewhere.
|
|
5
|
+
*/
|
|
6
|
+
import type { Signer } from "@mysten/sui/cryptography";
|
|
7
|
+
import { type WalrusClientConfig, type WriteBlobFlow } from "@mysten/walrus";
|
|
8
|
+
import type { QuiltPatchInput, StartBlobUploadResult, UploadBlobOptions, UploadBlobResult, UploadQuiltOptions, UploadQuiltResult, WalrusFlowCapable, WalrusWriteAdapter } from "./adapter.js";
|
|
9
|
+
/**
|
|
10
|
+
* Narrow structural slice of `WalrusClient` used by the adapter. Internal
|
|
11
|
+
* to the SDK; consumers should pass a real `WalrusClient` (or a structural
|
|
12
|
+
* mock in tests) without importing this name. Mutable arrays match the
|
|
13
|
+
* upstream `@mysten/walrus` types so the constructor cast is single-step.
|
|
14
|
+
*/
|
|
15
|
+
interface WalrusWriteClient {
|
|
16
|
+
writeBlob(args: {
|
|
17
|
+
blob: Uint8Array;
|
|
18
|
+
deletable: boolean;
|
|
19
|
+
epochs: number;
|
|
20
|
+
signer: Signer;
|
|
21
|
+
owner?: string;
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
blobId: string;
|
|
25
|
+
blobObject: {
|
|
26
|
+
id: string;
|
|
27
|
+
};
|
|
28
|
+
}>;
|
|
29
|
+
writeQuilt(args: {
|
|
30
|
+
blobs: Array<{
|
|
31
|
+
contents: Uint8Array;
|
|
32
|
+
identifier: string;
|
|
33
|
+
tags?: Record<string, string>;
|
|
34
|
+
}>;
|
|
35
|
+
deletable: boolean;
|
|
36
|
+
epochs: number;
|
|
37
|
+
signer: Signer;
|
|
38
|
+
owner?: string;
|
|
39
|
+
signal?: AbortSignal;
|
|
40
|
+
}): Promise<{
|
|
41
|
+
blobId: string;
|
|
42
|
+
blobObject: {
|
|
43
|
+
id: string;
|
|
44
|
+
};
|
|
45
|
+
index: {
|
|
46
|
+
patches: Array<{
|
|
47
|
+
patchId: string;
|
|
48
|
+
startIndex: number;
|
|
49
|
+
endIndex: number;
|
|
50
|
+
identifier: string;
|
|
51
|
+
}>;
|
|
52
|
+
};
|
|
53
|
+
}>;
|
|
54
|
+
writeBlobFlow(options: {
|
|
55
|
+
blob: Uint8Array;
|
|
56
|
+
}): WriteBlobFlow;
|
|
57
|
+
}
|
|
58
|
+
/** Construction options for `DefaultWalrusWriteAdapter`. */
|
|
59
|
+
export interface DefaultWalrusWriteAdapterOptions {
|
|
60
|
+
readonly client: WalrusWriteClient;
|
|
61
|
+
readonly signer: Signer;
|
|
62
|
+
}
|
|
63
|
+
/** Convenience options for `DefaultWalrusWriteAdapter.fromConfig`. */
|
|
64
|
+
export type WalrusAdapterConfig = WalrusClientConfig;
|
|
65
|
+
/** Default `WalrusWriteAdapter` wrapping `@mysten/walrus`. */
|
|
66
|
+
export declare class DefaultWalrusWriteAdapter implements WalrusWriteAdapter, WalrusFlowCapable {
|
|
67
|
+
private readonly client;
|
|
68
|
+
private readonly signer;
|
|
69
|
+
constructor(options: DefaultWalrusWriteAdapterOptions);
|
|
70
|
+
/**
|
|
71
|
+
* Build an adapter from a `WalrusClientConfig` and a signer. Equivalent
|
|
72
|
+
* to constructing the `WalrusClient` yourself and passing it in.
|
|
73
|
+
*/
|
|
74
|
+
static fromConfig(config: WalrusAdapterConfig, signer: Signer): DefaultWalrusWriteAdapter;
|
|
75
|
+
/**
|
|
76
|
+
* Upload a blob to Walrus end-to-end (register + upload + certify) in 2
|
|
77
|
+
* wallet popups, returning the certified blob's content id and Sui object
|
|
78
|
+
* id. For the common "upload then add as a new entry" flow, prefer
|
|
79
|
+
* `addEntryFromBytes`, which composes upload with `add_entry` into the
|
|
80
|
+
* same 2 popups. Use this when reusing a blob across multiple entries,
|
|
81
|
+
* pre-uploading on a server, or otherwise decoupling upload from entry
|
|
82
|
+
* creation.
|
|
83
|
+
*/
|
|
84
|
+
uploadBlob(data: Uint8Array, options: UploadBlobOptions): Promise<UploadBlobResult>;
|
|
85
|
+
/**
|
|
86
|
+
* Register and upload a blob without certifying it on-chain. Returns the
|
|
87
|
+
* blob's Sui object id, content id, and the certify `Transaction`. The
|
|
88
|
+
* caller is expected to append further move calls (e.g.
|
|
89
|
+
* `add_entry_to_collection`) to `certifyTransaction` and submit once,
|
|
90
|
+
* combining certify + downstream ops into a single wallet popup.
|
|
91
|
+
*
|
|
92
|
+
* The first wallet popup (register_blob) happens inside this call. The
|
|
93
|
+
* second popup is whoever submits `certifyTransaction`.
|
|
94
|
+
*
|
|
95
|
+
* Failure modes:
|
|
96
|
+
* - register fails -> throws `TransportError` with the underlying cause; nothing was uploaded
|
|
97
|
+
* - off-chain upload fails after register -> throws `TransportError`; the blob is registered but unuploaded (will eventually expire)
|
|
98
|
+
* - caller decides not to submit `certifyTransaction` -> blob remains registered+uploaded but uncertified; storage releases on registration expiry
|
|
99
|
+
*/
|
|
100
|
+
startBlobUpload(data: Uint8Array, options: UploadBlobOptions): Promise<StartBlobUploadResult>;
|
|
101
|
+
uploadQuilt(patches: readonly QuiltPatchInput[], options: UploadQuiltOptions): Promise<UploadQuiltResult>;
|
|
102
|
+
}
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=default-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-adapter.d.ts","sourceRoot":"","sources":["../../src/walrus/default-adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAGN,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAElB,MAAM,gBAAgB,CAAC;AAKxB,OAAO,KAAK,EACX,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAElB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,MAAM,cAAc,CAAC;AAGtB;;;;;GAKG;AACH,UAAU,iBAAiB;IAC1B,SAAS,CAAC,IAAI,EAAE;QACf,IAAI,EAAE,UAAU,CAAC;QACjB,SAAS,EAAE,OAAO,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,WAAW,CAAC;KACrB,GAAG,OAAO,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3B,CAAC,CAAC;IACH,UAAU,CAAC,IAAI,EAAE;QAChB,KAAK,EAAE,KAAK,CAAC;YACZ,QAAQ,EAAE,UAAU,CAAC;YACrB,UAAU,EAAE,MAAM,CAAC;YACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SAC9B,CAAC,CAAC;QACH,SAAS,EAAE,OAAO,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,WAAW,CAAC;KACrB,GAAG,OAAO,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC;QAC3B,KAAK,EAAE;YACN,OAAO,EAAE,KAAK,CAAC;gBACd,OAAO,EAAE,MAAM,CAAC;gBAChB,UAAU,EAAE,MAAM,CAAC;gBACnB,QAAQ,EAAE,MAAM,CAAC;gBACjB,UAAU,EAAE,MAAM,CAAC;aACnB,CAAC,CAAC;SACH,CAAC;KACF,CAAC,CAAC;IACH,aAAa,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,aAAa,CAAC;CAC5D;AAED,4DAA4D;AAC5D,MAAM,WAAW,gCAAgC;IAChD,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,sEAAsE;AACtE,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AAErD,8DAA8D;AAC9D,qBAAa,yBACZ,YAAW,kBAAkB,EAAE,iBAAiB;IAEhD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,EAAE,gCAAgC;IAKrD;;;OAGG;IACH,MAAM,CAAC,UAAU,CAChB,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,MAAM,GACZ,yBAAyB;IAO5B;;;;;;;;OAQG;IACG,UAAU,CACf,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,iBAAiB,GACxB,OAAO,CAAC,gBAAgB,CAAC;IAkB5B;;;;;;;;;;;;;;OAcG;IACG,eAAe,CACpB,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,iBAAiB,GACxB,OAAO,CAAC,qBAAqB,CAAC;IA4B3B,WAAW,CAChB,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,OAAO,EAAE,kBAAkB,GACzB,OAAO,CAAC,iBAAiB,CAAC;CAuC7B"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `WalrusWriteAdapter` implementation backed by `@mysten/walrus`. Bind a
|
|
3
|
+
* `WalrusClient` to a Sui `Signer` once, then call `uploadBlob` /
|
|
4
|
+
* `uploadQuilt` per write. Read paths live elsewhere.
|
|
5
|
+
*/
|
|
6
|
+
import { UserAbortError, WalrusClient, } from "@mysten/walrus";
|
|
7
|
+
import { toBlobObjectId, toWalrusBlobId } from "../codecs.js";
|
|
8
|
+
import { TransportError, ValidationError } from "../errors.js";
|
|
9
|
+
import { quiltPatchIdFromString } from "./quilt-patch-id.js";
|
|
10
|
+
/** Default `WalrusWriteAdapter` wrapping `@mysten/walrus`. */
|
|
11
|
+
export class DefaultWalrusWriteAdapter {
|
|
12
|
+
client;
|
|
13
|
+
signer;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.client = options.client;
|
|
16
|
+
this.signer = options.signer;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build an adapter from a `WalrusClientConfig` and a signer. Equivalent
|
|
20
|
+
* to constructing the `WalrusClient` yourself and passing it in.
|
|
21
|
+
*/
|
|
22
|
+
static fromConfig(config, signer) {
|
|
23
|
+
return new DefaultWalrusWriteAdapter({
|
|
24
|
+
client: new WalrusClient(config),
|
|
25
|
+
signer,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Upload a blob to Walrus end-to-end (register + upload + certify) in 2
|
|
30
|
+
* wallet popups, returning the certified blob's content id and Sui object
|
|
31
|
+
* id. For the common "upload then add as a new entry" flow, prefer
|
|
32
|
+
* `addEntryFromBytes`, which composes upload with `add_entry` into the
|
|
33
|
+
* same 2 popups. Use this when reusing a blob across multiple entries,
|
|
34
|
+
* pre-uploading on a server, or otherwise decoupling upload from entry
|
|
35
|
+
* creation.
|
|
36
|
+
*/
|
|
37
|
+
async uploadBlob(data, options) {
|
|
38
|
+
const result = await runWalrusCall(() => this.client.writeBlob({
|
|
39
|
+
blob: data,
|
|
40
|
+
deletable: options.deletable,
|
|
41
|
+
epochs: options.epochs,
|
|
42
|
+
signer: this.signer,
|
|
43
|
+
...(options.owner === undefined ? {} : { owner: options.owner }),
|
|
44
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
45
|
+
}));
|
|
46
|
+
return {
|
|
47
|
+
blobId: toWalrusBlobId(result.blobId),
|
|
48
|
+
blobObjectId: toBlobObjectId(result.blobObject.id),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Register and upload a blob without certifying it on-chain. Returns the
|
|
53
|
+
* blob's Sui object id, content id, and the certify `Transaction`. The
|
|
54
|
+
* caller is expected to append further move calls (e.g.
|
|
55
|
+
* `add_entry_to_collection`) to `certifyTransaction` and submit once,
|
|
56
|
+
* combining certify + downstream ops into a single wallet popup.
|
|
57
|
+
*
|
|
58
|
+
* The first wallet popup (register_blob) happens inside this call. The
|
|
59
|
+
* second popup is whoever submits `certifyTransaction`.
|
|
60
|
+
*
|
|
61
|
+
* Failure modes:
|
|
62
|
+
* - register fails -> throws `TransportError` with the underlying cause; nothing was uploaded
|
|
63
|
+
* - off-chain upload fails after register -> throws `TransportError`; the blob is registered but unuploaded (will eventually expire)
|
|
64
|
+
* - caller decides not to submit `certifyTransaction` -> blob remains registered+uploaded but uncertified; storage releases on registration expiry
|
|
65
|
+
*/
|
|
66
|
+
async startBlobUpload(data, options) {
|
|
67
|
+
return runWalrusCall(async () => {
|
|
68
|
+
const flow = this.client.writeBlobFlow({ blob: data });
|
|
69
|
+
await flow.encode();
|
|
70
|
+
const registered = await flow.executeRegister({
|
|
71
|
+
epochs: options.epochs,
|
|
72
|
+
deletable: options.deletable,
|
|
73
|
+
signer: this.signer,
|
|
74
|
+
owner: options.owner ?? this.signer.toSuiAddress(),
|
|
75
|
+
});
|
|
76
|
+
// Walrus's writeBlobFlow.upload() requires the register tx digest
|
|
77
|
+
// (or a resume.blobObjectId from a previous session) to know which
|
|
78
|
+
// on-chain blob the off-chain bytes belong to. Mirrors Walrus's own
|
|
79
|
+
// `run()` implementation; without this `upload()` throws
|
|
80
|
+
// "Either resume.blobObjectId or upload digest must be provided".
|
|
81
|
+
await flow.upload({
|
|
82
|
+
digest: registered.txDigest,
|
|
83
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
84
|
+
});
|
|
85
|
+
const certifyTransaction = flow.certify();
|
|
86
|
+
return {
|
|
87
|
+
blobObjectId: toBlobObjectId(registered.blobObjectId),
|
|
88
|
+
blobId: toWalrusBlobId(registered.blobId),
|
|
89
|
+
certifyTransaction,
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async uploadQuilt(patches, options) {
|
|
94
|
+
if (patches.length === 0) {
|
|
95
|
+
throw new ValidationError("uploadQuilt requires at least one patch", "patches");
|
|
96
|
+
}
|
|
97
|
+
const result = await runWalrusCall(() => this.client.writeQuilt({
|
|
98
|
+
blobs: patches.map((p) => ({
|
|
99
|
+
contents: p.contents,
|
|
100
|
+
identifier: p.identifier,
|
|
101
|
+
...(p.tags === undefined ? {} : { tags: { ...p.tags } }),
|
|
102
|
+
})),
|
|
103
|
+
deletable: options.deletable,
|
|
104
|
+
epochs: options.epochs,
|
|
105
|
+
signer: this.signer,
|
|
106
|
+
...(options.owner === undefined ? {} : { owner: options.owner }),
|
|
107
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
108
|
+
}));
|
|
109
|
+
const blobId = toWalrusBlobId(result.blobId);
|
|
110
|
+
const decoded = result.index.patches.map((p) => {
|
|
111
|
+
const patchId = quiltPatchIdFromString(p.patchId);
|
|
112
|
+
return {
|
|
113
|
+
identifier: p.identifier,
|
|
114
|
+
patchId,
|
|
115
|
+
startIndex: p.startIndex,
|
|
116
|
+
endIndex: p.endIndex,
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
return {
|
|
120
|
+
blobId,
|
|
121
|
+
blobObjectId: toBlobObjectId(result.blobObject.id),
|
|
122
|
+
patches: decoded,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async function runWalrusCall(call) {
|
|
127
|
+
try {
|
|
128
|
+
return await call();
|
|
129
|
+
}
|
|
130
|
+
catch (cause) {
|
|
131
|
+
if (cause instanceof ValidationError || cause instanceof TransportError) {
|
|
132
|
+
throw cause;
|
|
133
|
+
}
|
|
134
|
+
if (cause instanceof UserAbortError) {
|
|
135
|
+
throw new TransportError("Walrus call aborted by caller", { cause });
|
|
136
|
+
}
|
|
137
|
+
throw new TransportError(walrusErrorMessage(cause), { cause });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function walrusErrorMessage(cause) {
|
|
141
|
+
if (cause instanceof Error) {
|
|
142
|
+
return `Walrus call failed: ${cause.message}`;
|
|
143
|
+
}
|
|
144
|
+
return "Walrus call failed";
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=default-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-adapter.js","sourceRoot":"","sources":["../../src/walrus/default-adapter.ts"],"names":[],"mappings":"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"}
|