@arkade-os/sdk 0.4.2 → 0.4.4
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.
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DelegatorManagerImpl = void 0;
|
|
4
|
+
exports.findDestinationOutputIndex = findDestinationOutputIndex;
|
|
4
5
|
const __1 = require("..");
|
|
5
6
|
const base_1 = require("@scure/base");
|
|
6
7
|
const base_2 = require("../script/base");
|
|
7
8
|
const forfeit_1 = require("../forfeit");
|
|
8
9
|
const btc_signer_1 = require("@scure/btc-signer");
|
|
10
|
+
const utils_js_1 = require("@scure/btc-signer/utils.js");
|
|
9
11
|
const networks_1 = require("../networks");
|
|
10
12
|
const asset_1 = require("./asset");
|
|
11
13
|
const extension_1 = require("../extension");
|
|
@@ -173,7 +175,7 @@ async function delegate(identity, delegatorProvider, arkInfoProvider, vtxos, des
|
|
|
173
175
|
script: destinationScript,
|
|
174
176
|
amount: amount,
|
|
175
177
|
});
|
|
176
|
-
const registerIntent = await makeSignedDelegateIntent(identity, vtxos, outputs, [], [pubkey], delegateAtSeconds);
|
|
178
|
+
const registerIntent = await makeSignedDelegateIntent(identity, vtxos, outputs, [], [pubkey], delegateAtSeconds, destinationScript);
|
|
177
179
|
const forfeitOutputScript = btc_signer_1.OutScript.encode((0, btc_signer_1.Address)((0, networks_1.getNetwork)(network)).decode(forfeitAddress));
|
|
178
180
|
const forfeits = await Promise.all(vtxos
|
|
179
181
|
.filter((v) => !(0, __1.isRecoverable)(v))
|
|
@@ -218,7 +220,7 @@ async function makeDelegateForfeitTx(input, connectorAmount, delegatePubkey, for
|
|
|
218
220
|
});
|
|
219
221
|
return identity.sign(tx);
|
|
220
222
|
}
|
|
221
|
-
async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputsIndexes, cosignerPubKeys, validAt) {
|
|
223
|
+
async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputsIndexes, cosignerPubKeys, validAt, destinationScript) {
|
|
222
224
|
// if some of the inputs hold assets, build the asset packet and append as output
|
|
223
225
|
// in the intent proof tx, there is a "fake" input at index 0
|
|
224
226
|
// so the real coin indices are offset by +1
|
|
@@ -232,8 +234,11 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
|
|
|
232
234
|
}
|
|
233
235
|
}
|
|
234
236
|
let outputAssets;
|
|
235
|
-
|
|
237
|
+
const assetOutputIndex = findDestinationOutputIndex(outputs, destinationScript);
|
|
236
238
|
if (assetInputs.size > 0) {
|
|
239
|
+
if (assetOutputIndex === -1) {
|
|
240
|
+
throw new Error("Cannot assign assets: no output matches the destination address");
|
|
241
|
+
}
|
|
237
242
|
// collect all input assets and assign them to the first offchain output
|
|
238
243
|
const allAssets = new Map();
|
|
239
244
|
for (const [, assets] of assetInputs) {
|
|
@@ -246,11 +251,6 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
|
|
|
246
251
|
for (const [assetId, amount] of allAssets) {
|
|
247
252
|
outputAssets.push({ assetId, amount: Number(amount) });
|
|
248
253
|
}
|
|
249
|
-
const firstOffchainIndex = outputs.findIndex((_, i) => !onchainOutputsIndexes.includes(i));
|
|
250
|
-
if (firstOffchainIndex === -1) {
|
|
251
|
-
throw new Error("Cannot settle assets without an offchain output");
|
|
252
|
-
}
|
|
253
|
-
assetOutputIndex = firstOffchainIndex;
|
|
254
254
|
}
|
|
255
255
|
const recipients = outputs.map((output, i) => ({
|
|
256
256
|
address: "", // not needed for asset packet creation
|
|
@@ -275,6 +275,13 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
|
|
|
275
275
|
message,
|
|
276
276
|
};
|
|
277
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* Finds the index of the output whose script matches the destination script.
|
|
280
|
+
* Returns -1 if no match is found.
|
|
281
|
+
*/
|
|
282
|
+
function findDestinationOutputIndex(outputs, destinationScript) {
|
|
283
|
+
return outputs.findIndex((o) => o.script && (0, utils_js_1.equalBytes)(o.script, destinationScript));
|
|
284
|
+
}
|
|
278
285
|
function getDayTimestamp(timestamp) {
|
|
279
286
|
const date = new Date(timestamp);
|
|
280
287
|
date.setUTCHours(0, 0, 0, 0);
|
|
@@ -888,9 +888,13 @@ class Wallet extends ReadonlyWallet {
|
|
|
888
888
|
}
|
|
889
889
|
}
|
|
890
890
|
let outputAssets;
|
|
891
|
-
|
|
891
|
+
const destinationScript = address_1.ArkAddress.decode(await this.getAddress()).pkScript;
|
|
892
|
+
const assetOutputIndex = (0, delegator_1.findDestinationOutputIndex)(outputs, destinationScript);
|
|
892
893
|
if (assetInputs.size > 0) {
|
|
893
|
-
|
|
894
|
+
if (assetOutputIndex === -1) {
|
|
895
|
+
throw new Error("Cannot assign assets: no output matches the destination address");
|
|
896
|
+
}
|
|
897
|
+
// collect all input assets and assign them to the destination output
|
|
894
898
|
const allAssets = new Map();
|
|
895
899
|
for (const [, assets] of assetInputs) {
|
|
896
900
|
for (const asset of assets) {
|
|
@@ -902,11 +906,6 @@ class Wallet extends ReadonlyWallet {
|
|
|
902
906
|
for (const [assetId, amount] of allAssets) {
|
|
903
907
|
outputAssets.push({ assetId, amount: Number(amount) });
|
|
904
908
|
}
|
|
905
|
-
const firstOffchainIndex = params.outputs.findIndex((_, i) => !onchainOutputIndexes.includes(i));
|
|
906
|
-
if (firstOffchainIndex === -1) {
|
|
907
|
-
throw new Error("Cannot settle assets without an offchain output");
|
|
908
|
-
}
|
|
909
|
-
assetOutputIndex = firstOffchainIndex;
|
|
910
909
|
}
|
|
911
910
|
const recipients = params.outputs.map((output, i) => ({
|
|
912
911
|
address: output.address,
|
|
@@ -3,6 +3,7 @@ import { base64, hex } from "@scure/base";
|
|
|
3
3
|
import { scriptFromTapLeafScript } from '../script/base.js';
|
|
4
4
|
import { buildForfeitTxWithOutput } from '../forfeit.js';
|
|
5
5
|
import { Address, OutScript, SigHash } from "@scure/btc-signer";
|
|
6
|
+
import { equalBytes } from "@scure/btc-signer/utils.js";
|
|
6
7
|
import { getNetwork } from '../networks.js';
|
|
7
8
|
import { createAssetPacket } from './asset.js';
|
|
8
9
|
import { Extension } from '../extension/index.js';
|
|
@@ -169,7 +170,7 @@ async function delegate(identity, delegatorProvider, arkInfoProvider, vtxos, des
|
|
|
169
170
|
script: destinationScript,
|
|
170
171
|
amount: amount,
|
|
171
172
|
});
|
|
172
|
-
const registerIntent = await makeSignedDelegateIntent(identity, vtxos, outputs, [], [pubkey], delegateAtSeconds);
|
|
173
|
+
const registerIntent = await makeSignedDelegateIntent(identity, vtxos, outputs, [], [pubkey], delegateAtSeconds, destinationScript);
|
|
173
174
|
const forfeitOutputScript = OutScript.encode(Address(getNetwork(network)).decode(forfeitAddress));
|
|
174
175
|
const forfeits = await Promise.all(vtxos
|
|
175
176
|
.filter((v) => !isRecoverable(v))
|
|
@@ -214,7 +215,7 @@ async function makeDelegateForfeitTx(input, connectorAmount, delegatePubkey, for
|
|
|
214
215
|
});
|
|
215
216
|
return identity.sign(tx);
|
|
216
217
|
}
|
|
217
|
-
async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputsIndexes, cosignerPubKeys, validAt) {
|
|
218
|
+
async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputsIndexes, cosignerPubKeys, validAt, destinationScript) {
|
|
218
219
|
// if some of the inputs hold assets, build the asset packet and append as output
|
|
219
220
|
// in the intent proof tx, there is a "fake" input at index 0
|
|
220
221
|
// so the real coin indices are offset by +1
|
|
@@ -228,8 +229,11 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
|
|
|
228
229
|
}
|
|
229
230
|
}
|
|
230
231
|
let outputAssets;
|
|
231
|
-
|
|
232
|
+
const assetOutputIndex = findDestinationOutputIndex(outputs, destinationScript);
|
|
232
233
|
if (assetInputs.size > 0) {
|
|
234
|
+
if (assetOutputIndex === -1) {
|
|
235
|
+
throw new Error("Cannot assign assets: no output matches the destination address");
|
|
236
|
+
}
|
|
233
237
|
// collect all input assets and assign them to the first offchain output
|
|
234
238
|
const allAssets = new Map();
|
|
235
239
|
for (const [, assets] of assetInputs) {
|
|
@@ -242,11 +246,6 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
|
|
|
242
246
|
for (const [assetId, amount] of allAssets) {
|
|
243
247
|
outputAssets.push({ assetId, amount: Number(amount) });
|
|
244
248
|
}
|
|
245
|
-
const firstOffchainIndex = outputs.findIndex((_, i) => !onchainOutputsIndexes.includes(i));
|
|
246
|
-
if (firstOffchainIndex === -1) {
|
|
247
|
-
throw new Error("Cannot settle assets without an offchain output");
|
|
248
|
-
}
|
|
249
|
-
assetOutputIndex = firstOffchainIndex;
|
|
250
249
|
}
|
|
251
250
|
const recipients = outputs.map((output, i) => ({
|
|
252
251
|
address: "", // not needed for asset packet creation
|
|
@@ -271,6 +270,13 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
|
|
|
271
270
|
message,
|
|
272
271
|
};
|
|
273
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Finds the index of the output whose script matches the destination script.
|
|
275
|
+
* Returns -1 if no match is found.
|
|
276
|
+
*/
|
|
277
|
+
export function findDestinationOutputIndex(outputs, destinationScript) {
|
|
278
|
+
return outputs.findIndex((o) => o.script && equalBytes(o.script, destinationScript));
|
|
279
|
+
}
|
|
274
280
|
function getDayTimestamp(timestamp) {
|
|
275
281
|
const date = new Date(timestamp);
|
|
276
282
|
date.setUTCHours(0, 0, 0, 0);
|
|
@@ -27,7 +27,7 @@ import { buildTransactionHistory } from '../utils/transactionHistory.js';
|
|
|
27
27
|
import { AssetManager, ReadonlyAssetManager } from './asset-manager.js';
|
|
28
28
|
import { Extension } from '../extension/index.js';
|
|
29
29
|
import { DelegateVtxo } from '../script/delegate.js';
|
|
30
|
-
import { DelegatorManagerImpl } from './delegator.js';
|
|
30
|
+
import { DelegatorManagerImpl, findDestinationOutputIndex, } from './delegator.js';
|
|
31
31
|
import { IndexedDBContractRepository, IndexedDBWalletRepository, } from '../repositories/index.js';
|
|
32
32
|
import { ContractManager } from '../contracts/contractManager.js';
|
|
33
33
|
import { contractHandlers } from '../contracts/handlers/index.js';
|
|
@@ -882,9 +882,13 @@ export class Wallet extends ReadonlyWallet {
|
|
|
882
882
|
}
|
|
883
883
|
}
|
|
884
884
|
let outputAssets;
|
|
885
|
-
|
|
885
|
+
const destinationScript = ArkAddress.decode(await this.getAddress()).pkScript;
|
|
886
|
+
const assetOutputIndex = findDestinationOutputIndex(outputs, destinationScript);
|
|
886
887
|
if (assetInputs.size > 0) {
|
|
887
|
-
|
|
888
|
+
if (assetOutputIndex === -1) {
|
|
889
|
+
throw new Error("Cannot assign assets: no output matches the destination address");
|
|
890
|
+
}
|
|
891
|
+
// collect all input assets and assign them to the destination output
|
|
888
892
|
const allAssets = new Map();
|
|
889
893
|
for (const [, assets] of assetInputs) {
|
|
890
894
|
for (const asset of assets) {
|
|
@@ -896,11 +900,6 @@ export class Wallet extends ReadonlyWallet {
|
|
|
896
900
|
for (const [assetId, amount] of allAssets) {
|
|
897
901
|
outputAssets.push({ assetId, amount: Number(amount) });
|
|
898
902
|
}
|
|
899
|
-
const firstOffchainIndex = params.outputs.findIndex((_, i) => !onchainOutputIndexes.includes(i));
|
|
900
|
-
if (firstOffchainIndex === -1) {
|
|
901
|
-
throw new Error("Cannot settle assets without an offchain output");
|
|
902
|
-
}
|
|
903
|
-
assetOutputIndex = firstOffchainIndex;
|
|
904
903
|
}
|
|
905
904
|
const recipients = params.outputs.map((output, i) => ({
|
|
906
905
|
address: output.address,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { TransactionOutput } from "@scure/btc-signer/psbt";
|
|
1
2
|
import { ArkProvider, DelegateInfo, ExtendedVirtualCoin, Identity, Outpoint } from "..";
|
|
2
3
|
import { DelegatorProvider } from "../providers/delegator";
|
|
4
|
+
import { Bytes } from "@scure/btc-signer/utils";
|
|
3
5
|
export interface IDelegatorManager {
|
|
4
6
|
delegate(vtxos: ExtendedVirtualCoin[], destination: string, delegateAt?: Date): Promise<{
|
|
5
7
|
delegated: Outpoint[];
|
|
@@ -24,3 +26,8 @@ export declare class DelegatorManagerImpl implements IDelegatorManager {
|
|
|
24
26
|
}[];
|
|
25
27
|
}>;
|
|
26
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Finds the index of the output whose script matches the destination script.
|
|
31
|
+
* Returns -1 if no match is found.
|
|
32
|
+
*/
|
|
33
|
+
export declare function findDestinationOutputIndex(outputs: TransactionOutput[], destinationScript: Bytes): number;
|