Skip to content

Commit 950306e

Browse files
Merge pull request #159 from paritytech/fix-deploy-paseo-v2-env
fix: wire deploys to paseo next v2
2 parents 62925ac + a203503 commit 950306e

19 files changed

Lines changed: 238 additions & 96 deletions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"playground-cli": patch
3+
---
4+
5+
Pass the selected deploy environment through to `bulletin-deploy`, pin the paseo-next-v2 capable `bulletin-deploy` prerelease, resolve live CDM contracts through the active `cdm.json` target registry, pass the Asset Hub descriptor to playground registry handles, use the paseo-next-v2 IPFS gateway path for playground metadata reads, use `--suri` signers for DotNS in dev-mode deploys, and treat bare mnemonic SURIs as the root account.

cdm.json

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
11
{
22
"targets": {
3-
"4963ba95e259237b": {
4-
"asset-hub": "wss://paseo-asset-hub-next-rpc.polkadot.io",
5-
"bulletin": "https://paseo-bulletin-next-ipfs.polkadot.io",
6-
"registry": "0x5c7b23d386ff622c7f7a4e7a95d5c7a67b10a00d"
7-
},
83
"8e7e0cf0a51d8e5e": {
94
"asset-hub": "wss://paseo-asset-hub-next-rpc.polkadot.io",
105
"bulletin": "https://paseo-bulletin-next-ipfs.polkadot.io/ipfs",
116
"registry": "0x5c7b23d386ff622c7f7a4e7a95d5c7a67b10a00d"
127
}
138
},
149
"dependencies": {
15-
"4963ba95e259237b": {},
1610
"8e7e0cf0a51d8e5e": {
1711
"@w3s/playground-registry": "latest"
1812
}
1913
},
2014
"contracts": {
21-
"4963ba95e259237b": {},
2215
"8e7e0cf0a51d8e5e": {
2316
"@w3s/playground-registry": {
2417
"version": 0,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"@parity/product-sdk-utils": "^0.1.1",
4141
"@polkadot-api/sdk-ink": "^0.7.0",
4242
"@sentry/node": "^9.47.1",
43-
"bulletin-deploy": "0.7.19",
43+
"bulletin-deploy": "0.7.20-rc.4",
4444
"commander": "^12.0.0",
4545
"ink": "^5.2.1",
4646
"polkadot-api": "^2.1.2",

pnpm-lock.yaml

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/commands/deploy/DeployScreen.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,13 @@ export function DeployScreen({
292292
{stage.kind === "validate-domain" && (
293293
<ValidateDomainStage
294294
domain={stage.domain}
295-
// Only gate on the user's address in phone mode — see
296-
// `ownerSs58Address` docs in availability.ts. In dev mode
297-
// bulletin-deploy signs DotNS with its own DEFAULT_MNEMONIC,
298-
// so the user's H160 does not match the registrar's H160
299-
// and the preflight would mis-report re-deploys as "taken".
300-
ownerSs58Address={mode === "phone" ? userSigner?.address : undefined}
295+
ownerSs58Address={
296+
mode === "phone"
297+
? userSigner?.address
298+
: userSigner?.source === "dev"
299+
? userSigner.address
300+
: undefined
301+
}
301302
onAvailable={(result) => {
302303
setDomain(result.fullDomain);
303304
setPlan(result.plan);

src/commands/deploy/index.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -308,21 +308,24 @@ async function runHeadless(ctx: {
308308
//
309309
// `ownerSs58Address` MUST match whoever will actually sign the DotNS
310310
// `register()` extrinsic — otherwise the preflight reports "taken" on a
311-
// re-deploy. In phone mode bulletin-deploy uses the user's signer, so
312-
// passing the user's address is correct. In dev mode bulletin-deploy
313-
// falls back to its built-in DEFAULT_MNEMONIC, so the user's H160 does
314-
// NOT match the on-chain owner — we omit the address and let
315-
// bulletin-deploy's own preflight (run with the right signer during
316-
// `deploy()`) do the comparison.
311+
// re-deploy. Phone mode signs with the session account; dev-with-SURI signs
312+
// with that local account. Pure dev mode still falls back to bulletin-deploy's
313+
// built-in DEFAULT_MNEMONIC, so we omit the address there.
317314
process.stdout.write(`\nChecking availability of ${domain.replace(/\.dot$/, "") + ".dot"}…\n`);
315+
const dotnsOwnerSs58Address =
316+
mode === "phone"
317+
? ctx.userSigner?.address
318+
: ctx.userSigner?.source === "dev"
319+
? ctx.userSigner.address
320+
: undefined;
318321
const availability = await withSpan(
319322
"cli.deploy.availability",
320323
"check domain availability",
321324
{ "cli.deploy.domain": domain.replace(/\.dot$/, "") },
322325
() =>
323326
checkDomainAvailability(domain, {
324327
env: ctx.env,
325-
ownerSs58Address: mode === "phone" ? ctx.userSigner?.address : undefined,
328+
ownerSs58Address: dotnsOwnerSs58Address,
326329
}),
327330
);
328331
if (availability.status !== "available") {

src/config.ts

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
* today; others throw from `getChainConfig` until they're populated.
2424
*/
2525

26-
import { REGISTRY_ADDRESS } from "@dotdm/contracts";
27-
2826
export type Env =
2927
| "preview"
3028
| "paseo-next"
@@ -36,23 +34,6 @@ export type Env =
3634
export const ACTIVE_TESTNET_ENV: Env = "paseo-next-v2";
3735
export const DEFAULT_ENV: Env = ACTIVE_TESTNET_ENV;
3836

39-
/**
40-
* DotNS contract addresses for an env. Resolved by bulletin-deploy when
41-
* `skipDotnsCli: true`; included here so other callers (mod, registry
42-
* lookups) can read the live set without re-parsing bulletin-deploy's bundled
43-
* environments.json.
44-
*/
45-
export interface DotnsContracts {
46-
REGISTRAR: string;
47-
REGISTRAR_CONTROLLER: string;
48-
REGISTRY: string;
49-
RESOLVER: string;
50-
CONTENT_RESOLVER: string;
51-
REVERSE_RESOLVER: string;
52-
POP_RULES: string;
53-
STORE_FACTORY: string;
54-
}
55-
5637
export interface ChainConfig {
5738
/** Env identifier — passes straight through to bulletin-deploy's `deploy({ env })`. */
5839
env: Env;
@@ -83,14 +64,12 @@ export interface ChainConfig {
8364
autoAccountMapping: boolean;
8465
/** True when `authorize_account` takes the v2 `{who, transactions, bytes}` signature. */
8566
bulletinAuthorizeV2: boolean;
86-
/** DotNS contract addresses. null when bulletin-deploy/dotns-cli has hardcoded defaults. */
87-
dotnsContracts: DotnsContracts | null;
8867
/** Public faucet URL, or null when allowances replace the funder flow. */
8968
faucetUrl: string | null;
9069
}
9170

92-
// Paseo Next v2 — the active env. Source for endpoints + DotNS addresses:
93-
// bulletin-deploy/assets/environments.json (v2 entry).
71+
// Paseo Next v2 — the active env. DotNS contracts are owned by
72+
// bulletin-deploy's environment catalog and keyed by `env`.
9473
const PASEO_NEXT_V2: ChainConfig = {
9574
env: "paseo-next-v2",
9675
network: "testnet",
@@ -99,21 +78,11 @@ const PASEO_NEXT_V2: ChainConfig = {
9978
bulletinRpc: "wss://paseo-bulletin-next-rpc.polkadot.io",
10079
bulletinRpcFallbacks: [],
10180
peopleEndpoints: ["wss://paseo-people-next-system-rpc.polkadot.io"],
102-
bulletinGateway: "https://paseo-bulletin-next-ipfs.polkadot.io/",
81+
bulletinGateway: "https://paseo-bulletin-next-ipfs.polkadot.io/ipfs/",
10382
identityBackendUrl: "https://identity-backend-next.parity-testnet.parity.io",
10483
appViewerOrigin: "https://dot.li",
10584
autoAccountMapping: true,
10685
bulletinAuthorizeV2: true,
107-
dotnsContracts: {
108-
REGISTRAR: "0xE67B22B285912FFfaE23BdfAc8C80c779d99B3e0",
109-
REGISTRAR_CONTROLLER: "0x8403e49Ec12F4EA5788f7bc0C0c2F649205774cC",
110-
REGISTRY: "0xDeFE1AAE21eC2455bd04b213a51C16d4b426c7ef",
111-
RESOLVER: "0xB436A271Beff1DBa6abDf2dbCc7E6d723d505EE6",
112-
CONTENT_RESOLVER: "0xBcFa907Ff85dFc62a21b41d48F23D7A73aC42914",
113-
REVERSE_RESOLVER: "0x4Ca32Dd0233D8c1B1709e20D9E4edBF2a77D21c3",
114-
POP_RULES: "0xd3F059FA65dA566B294b5d755a06054d4bE7ce7C",
115-
STORE_FACTORY: "0x4f1885fB6e0b154dCf9C2A8661e578B94aD50775",
116-
},
11786
faucetUrl: null,
11887
};
11988

@@ -179,9 +148,6 @@ export function getNetworkLabel(env: Env = DEFAULT_ENV): string {
179148
}
180149
}
181150

182-
/** CDM meta-registry contract address, sourced from `@dotdm/contracts`. */
183-
export const CDM_REGISTRY_ADDRESS = REGISTRY_ADDRESS;
184-
185151
/** Identifier the terminal adapter reports during SSO. Kept stable so mobile pairings persist across releases. */
186152
export const DAPP_ID = "dot-cli";
187153

src/utils/bulletinGateway.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ describe("bulletinGatewayUrl", () => {
4040
describe("getBulletinGateway", () => {
4141
it("returns the paseo-next-v2 gateway by default", () => {
4242
// Defaults to DEFAULT_ENV (paseo-next-v2); no env arg required.
43-
expect(getBulletinGateway()).toBe("https://paseo-bulletin-next-ipfs.polkadot.io/");
43+
expect(getBulletinGateway()).toBe("https://paseo-bulletin-next-ipfs.polkadot.io/ipfs/");
4444
});
4545

4646
it("returns the same URL when explicitly asked for paseo-next-v2", () => {
4747
expect(getBulletinGateway("paseo-next-v2")).toBe(
48-
"https://paseo-bulletin-next-ipfs.polkadot.io/",
48+
"https://paseo-bulletin-next-ipfs.polkadot.io/ipfs/",
4949
);
5050
});
5151
});

src/utils/contractManifest.test.ts

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import { describe, expect, it, beforeEach, vi } from "vitest";
1717
import type { CdmJson } from "@parity/product-sdk-contracts";
18-
import { CDM_REGISTRY_ADDRESS } from "../config.js";
18+
import { REGISTRY_ADDRESS } from "@dotdm/contracts";
1919

2020
const { createContractFromClientMock, getAddressQueryMock } = vi.hoisted(() => ({
2121
createContractFromClientMock: vi.fn(),
@@ -26,6 +26,10 @@ vi.mock("@parity/product-sdk-contracts", () => ({
2626
createContractFromClient: (...args: unknown[]) => createContractFromClientMock(...args),
2727
}));
2828

29+
vi.mock("@parity/product-sdk-descriptors/paseo-asset-hub", () => ({
30+
paseo_asset_hub: { genesis: "0xasset" },
31+
}));
32+
2933
import {
3034
PLAYGROUND_REGISTRY_CONTRACT,
3135
resolveLiveContractAddresses,
@@ -35,6 +39,7 @@ import {
3539

3640
const snapshotAddress = "0x1111111111111111111111111111111111111111";
3741
const liveAddress = "0x2222222222222222222222222222222222222222";
42+
const targetRegistryAddress = "0x5555555555555555555555555555555555555555";
3843

3944
/**
4045
* Mock `Weight` for `QueryResult.gasRequired` — required (non-optional) on
@@ -50,6 +55,7 @@ function manifest(): CdmJson {
5055
target1: {
5156
"asset-hub": "wss://asset-hub.example",
5257
bulletin: "https://bulletin.example/ipfs",
58+
registry: targetRegistryAddress,
5359
},
5460
},
5561
dependencies: {
@@ -73,7 +79,7 @@ function manifest(): CdmJson {
7379
},
7480
},
7581
},
76-
};
82+
} as CdmJson;
7783
}
7884

7985
beforeEach(() => {
@@ -85,22 +91,25 @@ beforeEach(() => {
8591
});
8692

8793
describe("resolveLiveContractAddresses", () => {
88-
it("queries the fixed CDM registry for requested libraries", async () => {
94+
it("queries the configured CDM registry for requested libraries", async () => {
8995
getAddressQueryMock.mockResolvedValue({
9096
success: true,
9197
value: { isSome: true, value: liveAddress },
9298
gasRequired: OK_WEIGHT,
9399
});
94100

95101
const assetHub = {} as any;
96-
const addresses = await resolveLiveContractAddresses(assetHub, [
97-
PLAYGROUND_REGISTRY_CONTRACT,
98-
]);
102+
const addresses = await resolveLiveContractAddresses(
103+
assetHub,
104+
[PLAYGROUND_REGISTRY_CONTRACT],
105+
{ registryAddress: targetRegistryAddress },
106+
);
99107

100108
expect(addresses).toEqual({ [PLAYGROUND_REGISTRY_CONTRACT]: liveAddress });
101109
expect(createContractFromClientMock).toHaveBeenCalledWith(
102110
assetHub,
103-
CDM_REGISTRY_ADDRESS,
111+
{ genesis: "0xasset" },
112+
targetRegistryAddress,
104113
expect.arrayContaining([
105114
expect.objectContaining({ name: "getAddress", type: "function" }),
106115
]),
@@ -120,11 +129,13 @@ describe("resolveLiveContractAddresses", () => {
120129
const origin = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";
121130
await resolveLiveContractAddresses(assetHub, [PLAYGROUND_REGISTRY_CONTRACT], {
122131
defaultOrigin: origin,
132+
registryAddress: targetRegistryAddress,
123133
});
124134

125135
expect(createContractFromClientMock).toHaveBeenCalledWith(
126136
assetHub,
127-
CDM_REGISTRY_ADDRESS,
137+
{ genesis: "0xasset" },
138+
targetRegistryAddress,
128139
expect.any(Array),
129140
expect.objectContaining({ defaultOrigin: origin }),
130141
);
@@ -138,9 +149,29 @@ describe("resolveLiveContractAddresses", () => {
138149
});
139150

140151
await expect(
141-
resolveLiveContractAddresses({} as any, [PLAYGROUND_REGISTRY_CONTRACT]),
152+
resolveLiveContractAddresses({} as any, [PLAYGROUND_REGISTRY_CONTRACT], {
153+
registryAddress: targetRegistryAddress,
154+
}),
142155
).resolves.toEqual({});
143156
});
157+
158+
it("falls back to CDM's package registry address when no registry is supplied", async () => {
159+
getAddressQueryMock.mockResolvedValue({
160+
success: true,
161+
value: { isSome: true, value: liveAddress },
162+
gasRequired: OK_WEIGHT,
163+
});
164+
165+
await resolveLiveContractAddresses({} as any, [PLAYGROUND_REGISTRY_CONTRACT]);
166+
167+
expect(createContractFromClientMock).toHaveBeenCalledWith(
168+
{},
169+
{ genesis: "0xasset" },
170+
REGISTRY_ADDRESS,
171+
expect.any(Array),
172+
expect.any(Object),
173+
);
174+
});
144175
});
145176

146177
describe("withLiveContractAddresses", () => {
@@ -200,7 +231,8 @@ describe("withLiveContractAddresses", () => {
200231

201232
expect(createContractFromClientMock).toHaveBeenCalledWith(
202233
assetHub,
203-
CDM_REGISTRY_ADDRESS,
234+
{ genesis: "0xasset" },
235+
targetRegistryAddress,
204236
expect.any(Array),
205237
expect.objectContaining({ defaultOrigin: origin }),
206238
);
@@ -224,7 +256,8 @@ describe("withLiveContractAddresses", () => {
224256

225257
expect(createContractFromClientMock).toHaveBeenCalledWith(
226258
assetHub,
227-
CDM_REGISTRY_ADDRESS,
259+
{ genesis: "0xasset" },
260+
targetRegistryAddress,
228261
expect.any(Array),
229262
expect.objectContaining({ defaultOrigin: origin }),
230263
);

0 commit comments

Comments
 (0)